1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/spdy/spdy_test_utils.h"
10 #include "base/base64.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/sys_byteorder.h"
15 #include "net/http/transport_security_state.h"
16 #include "net/ssl/ssl_info.h"
17 #include "testing/gtest/include/gtest/gtest.h"
22 std::string
HexDumpWithMarks(const unsigned char* data
, int length
,
23 const bool* marks
, int mark_length
) {
24 static const char kHexChars
[] = "0123456789abcdef";
25 static const int kColumns
= 4;
27 const int kSizeLimit
= 1024;
28 if (length
> kSizeLimit
|| mark_length
> kSizeLimit
) {
29 LOG(ERROR
) << "Only dumping first " << kSizeLimit
<< " bytes.";
30 length
= std::min(length
, kSizeLimit
);
31 mark_length
= std::min(mark_length
, kSizeLimit
);
35 for (const unsigned char* row
= data
; length
> 0;
36 row
+= kColumns
, length
-= kColumns
) {
37 for (const unsigned char *p
= row
; p
< row
+ 4; ++p
) {
38 if (p
< row
+ length
) {
40 (marks
&& (p
- data
) < mark_length
&& marks
[p
- data
]);
41 hex
+= mark
? '*' : ' ';
42 hex
+= kHexChars
[(*p
& 0xf0) >> 4];
43 hex
+= kHexChars
[*p
& 0x0f];
44 hex
+= mark
? '*' : ' ';
51 for (const unsigned char* p
= row
; p
< row
+ 4 && p
< row
+ length
; ++p
) {
52 hex
+= (*p
>= 0x20 && *p
<= 0x7f) ? (*p
) : '.';
60 void CompareCharArraysWithHexError(
61 const std::string
& description
,
62 const unsigned char* actual
,
64 const unsigned char* expected
,
65 const int expected_len
) {
66 const int min_len
= std::min(actual_len
, expected_len
);
67 const int max_len
= std::max(actual_len
, expected_len
);
68 scoped_ptr
<bool[]> marks(new bool[max_len
]);
69 bool identical
= (actual_len
== expected_len
);
70 for (int i
= 0; i
< min_len
; ++i
) {
71 if (actual
[i
] != expected
[i
]) {
78 for (int i
= min_len
; i
< max_len
; ++i
) {
81 if (identical
) return;
86 << HexDumpWithMarks(expected
, expected_len
, marks
.get(), max_len
)
88 << HexDumpWithMarks(actual
, actual_len
, marks
.get(), max_len
);
91 void SetFrameFlags(SpdyFrame
* frame
,
93 SpdyMajorVersion spdy_version
) {
94 switch (spdy_version
) {
98 frame
->data()[4] = flags
;
101 LOG(FATAL
) << "Unsupported SPDY version.";
105 void SetFrameLength(SpdyFrame
* frame
,
107 SpdyMajorVersion spdy_version
) {
108 switch (spdy_version
) {
111 CHECK_EQ(0u, length
& ~kLengthMask
);
113 int32 wire_length
= base::HostToNet32(length
);
114 // The length field in SPDY 2 and 3 is a 24-bit (3B) integer starting at
116 memcpy(frame
->data() + 5, reinterpret_cast<char*>(&wire_length
) + 1, 3);
120 CHECK_GT(1u<<14, length
);
122 int32 wire_length
= base::HostToNet32(length
);
123 memcpy(frame
->data(),
124 reinterpret_cast<char*>(&wire_length
) + 1,
129 LOG(FATAL
) << "Unsupported SPDY version.";
133 bool CompareSpdyHeaderBlocks(const SpdyHeaderBlock
& a
,
134 const SpdyHeaderBlock
& b
) {
135 return a
.size() == b
.size() && std::equal(a
.begin(), a
.end(), b
.begin());
138 std::string
a2b_hex(const char* hex_data
) {
139 std::vector
<uint8
> output
;
141 if (base::HexStringToBytes(hex_data
, &output
))
142 result
.assign(reinterpret_cast<const char*>(&output
[0]), output
.size());
146 HashValue
GetTestHashValue(uint8_t label
) {
147 HashValue
hash_value(HASH_VALUE_SHA256
);
148 memset(hash_value
.data(), label
, hash_value
.size());
152 std::string
GetTestPin(uint8_t label
) {
153 HashValue hash_value
= GetTestHashValue(label
);
155 base::Base64Encode(base::StringPiece(
156 reinterpret_cast<char*>(hash_value
.data()), hash_value
.size()), &base64
);
158 return std::string("pin-sha256=\"") + base64
+ "\"";
161 void AddPin(TransportSecurityState
* state
,
162 const std::string
& host
,
163 uint8_t primary_label
,
164 uint8_t backup_label
) {
165 std::string primary_pin
= GetTestPin(primary_label
);
166 std::string backup_pin
= GetTestPin(backup_label
);
167 std::string header
= "max-age = 10000; " + primary_pin
+ "; " + backup_pin
;
169 // Construct a fake SSLInfo that will pass AddHPKPHeader's checks.
171 ssl_info
.is_issued_by_known_root
= true;
172 ssl_info
.public_key_hashes
.push_back(GetTestHashValue(primary_label
));
173 EXPECT_TRUE(state
->AddHPKPHeader(host
, header
, ssl_info
));