1 #include "gtest/gtest.h"
3 #include "chrome/common/ipc_message.h"
4 #include "mozilla/net/PHttpChannelParams.h"
5 #include "mozilla/Unused.h"
7 #include "nsIPrefBranch.h"
8 #include "nsIPrefService.h"
9 #include "nsURLHelper.h"
14 void AssertRoundTrips(const nsHttpResponseHead
& aHead
) {
16 // Assert it round-trips via IPC.
17 UniquePtr
<IPC::Message
> msg(new IPC::Message(MSG_ROUTING_NONE
, 0));
18 IPC::MessageWriter
writer(*msg
);
19 IPC::ParamTraits
<nsHttpResponseHead
>::Write(&writer
, aHead
);
21 nsHttpResponseHead deserializedHead
;
22 IPC::MessageReader
reader(*msg
);
23 bool res
= IPC::ParamTraits
<mozilla::net::nsHttpResponseHead
>::Read(
24 &reader
, &deserializedHead
);
26 ASSERT_EQ(aHead
, deserializedHead
);
30 // Assert it round-trips through copy-ctor.
31 nsHttpResponseHead
copied(aHead
);
32 ASSERT_EQ(aHead
, copied
);
36 // Assert it round-trips through operator=
37 nsHttpResponseHead copied
;
39 // It is important that the below statement cannot be
40 // ASSERT_EQ(aHead, copied) to avoid potential lock-order inversion problem.
41 // See Bug 1829445 for more details
42 ASSERT_EQ(copied
, aHead
);
46 TEST(TestHttpResponseHead
, Bug1636930
)
48 nsHttpResponseHead head
;
50 Unused
<< head
.ParseStatusLine("HTTP/1.1 200 OK"_ns
);
51 Unused
<< head
.ParseHeaderLine("content-type: text/plain"_ns
);
52 Unused
<< head
.ParseHeaderLine("etag: Just testing"_ns
);
53 Unused
<< head
.ParseHeaderLine("cache-control: max-age=99999"_ns
);
54 Unused
<< head
.ParseHeaderLine("accept-ranges: bytes"_ns
);
55 Unused
<< head
.ParseHeaderLine("content-length: 1408"_ns
);
56 Unused
<< head
.ParseHeaderLine("connection: close"_ns
);
57 Unused
<< head
.ParseHeaderLine("server: httpd.js"_ns
);
58 Unused
<< head
.ParseHeaderLine("date: Tue, 12 May 2020 09:24:23 GMT"_ns
);
60 AssertRoundTrips(head
);
63 TEST(TestHttpResponseHead
, bug1649807
)
65 nsHttpResponseHead head
;
67 Unused
<< head
.ParseStatusLine("HTTP/1.1 200 OK"_ns
);
68 Unused
<< head
.ParseHeaderLine("content-type: text/plain"_ns
);
69 Unused
<< head
.ParseHeaderLine("etag: Just testing"_ns
);
70 Unused
<< head
.ParseHeaderLine("cache-control: age=99999"_ns
);
71 Unused
<< head
.ParseHeaderLine("accept-ranges: bytes"_ns
);
72 Unused
<< head
.ParseHeaderLine("content-length: 1408"_ns
);
73 Unused
<< head
.ParseHeaderLine("connection: close"_ns
);
74 Unused
<< head
.ParseHeaderLine("server: httpd.js"_ns
);
75 Unused
<< head
.ParseHeaderLine("pragma: no-cache"_ns
);
76 Unused
<< head
.ParseHeaderLine("date: Tue, 12 May 2020 09:24:23 GMT"_ns
);
78 ASSERT_FALSE(head
.NoCache())
79 << "Cache-Control wins over Pragma: no-cache";
80 AssertRoundTrips(head
);
83 TEST(TestHttpResponseHead
, bug1660200
)
85 nsHttpResponseHead head
;
87 Unused
<< head
.ParseStatusLine("HTTP/1.1 200 OK"_ns
);
88 Unused
<< head
.ParseHeaderLine("content-type: text/plain"_ns
);
89 Unused
<< head
.ParseHeaderLine("etag: Just testing"_ns
);
90 Unused
<< head
.ParseHeaderLine("cache-control: no-cache"_ns
);
91 Unused
<< head
.ParseHeaderLine("accept-ranges: bytes"_ns
);
92 Unused
<< head
.ParseHeaderLine("content-length: 1408"_ns
);
93 Unused
<< head
.ParseHeaderLine("connection: close"_ns
);
94 Unused
<< head
.ParseHeaderLine("server: httpd.js"_ns
);
95 Unused
<< head
.ParseHeaderLine("date: Tue, 12 May 2020 09:24:23 GMT"_ns
);
97 AssertRoundTrips(head
);
100 TEST(TestHttpResponseHead
, bug1687903
)
102 nsHttpResponseHead head
;
104 nsCOMPtr
<nsIPrefBranch
> prefs
= do_GetService(NS_PREFSERVICE_CONTRACTID
);
106 nsresult expectation
= NS_ERROR_PARSING_HTTP_STATUS_LINE
;
108 ASSERT_EQ(expectation
, head
.ParseStatusLine("HTTP/1.1 "_ns
));
109 ASSERT_EQ(expectation
, head
.ParseStatusLine("HTTP/1.1 BLAH"_ns
));
110 ASSERT_EQ(expectation
, head
.ParseStatusLine("HTTP/1.1 1000 BOO"_ns
));
111 ASSERT_EQ(expectation
, head
.ParseStatusLine("HTTP/1.1 0200 BOO"_ns
));
112 ASSERT_EQ(expectation
, head
.ParseStatusLine("HTTP/1.1 60200 200"_ns
));
113 ASSERT_EQ(expectation
, head
.ParseStatusLine("HTTP/1.1 131072 HIOK"_ns
));
114 ASSERT_EQ(expectation
, head
.ParseStatusLine("HTTP/1.1 -200 OK"_ns
));
115 ASSERT_EQ(expectation
, head
.ParseStatusLine("HTTP/1.1 0x9 OK"_ns
));
116 ASSERT_EQ(expectation
, head
.ParseStatusLine("HTTP/1.1 C8 OK"_ns
));
119 TEST(TestHttpResponseHead
, atoms
)
121 // Test that the resolving the content-type atom returns the initial static
122 ASSERT_EQ(nsHttp::Content_Type
, nsHttp::ResolveAtom("content-type"_ns
));
123 // Check that they're case insensitive
124 ASSERT_EQ(nsHttp::ResolveAtom("Content-Type"_ns
),
125 nsHttp::ResolveAtom("content-type"_ns
));
126 // This string literal should be the backing of the atom when resolved first
127 auto header1
= "CustomHeaderXXX1"_ns
;
128 auto atom1
= nsHttp::ResolveAtom(header1
);
129 auto header2
= "customheaderxxx1"_ns
;
130 auto atom2
= nsHttp::ResolveAtom(header2
);
131 ASSERT_EQ(atom1
, atom2
);
132 ASSERT_EQ(atom1
.get(), atom2
.get());
133 // Check that we get the expected pointer back.
134 ASSERT_EQ(atom2
.get(), header1
.BeginReading());
137 TEST(ContentTypeParsing
, CommentHandling1
)
140 const nsAutoCString
val("text/html;charset=gbk(");
141 nsCString contentType
;
142 nsCString contentCharset
;
144 net_ParseContentType(val
, contentType
, contentCharset
, &dummy
);
146 ASSERT_TRUE(contentType
.EqualsLiteral("text/html"));
147 ASSERT_TRUE(contentCharset
.EqualsLiteral("gbk("));
150 TEST(ContentTypeParsing
, CommentHandling2
)
153 const nsAutoCString
val("text/html;x=(;charset=gbk");
154 nsCString contentType
;
155 nsCString contentCharset
;
157 net_ParseContentType(val
, contentType
, contentCharset
, &dummy
);
159 ASSERT_TRUE(contentType
.EqualsLiteral("text/html"));
160 ASSERT_TRUE(contentCharset
.EqualsLiteral("gbk"));
163 TEST(ContentTypeParsing
, CommentHandling3
)
166 const nsAutoCString
val("text/html;test=test;(;charset=gbk");
167 nsCString contentType
;
168 nsCString contentCharset
;
170 net_ParseContentType(val
, contentType
, contentCharset
, &dummy
);
172 ASSERT_TRUE(contentType
.EqualsLiteral("text/html"));
173 ASSERT_TRUE(contentCharset
.EqualsLiteral("gbk"));
176 TEST(TestHttpResponseHead
, MoveConstructor
)
178 // Construct an initial response head
179 nsHttpResponseHead originalHead
;
180 Unused
<< originalHead
.ParseStatusLine("HTTP/1.1 200 OK"_ns
);
181 Unused
<< originalHead
.ParseHeaderLine("content-type: text/plain"_ns
);
182 Unused
<< originalHead
.ParseHeaderLine("content-length: 1408"_ns
);
184 // Move construct a new object from the initial one
185 nsHttpResponseHead
movedHead(std::move(originalHead
));
187 // Ensure the moved head retains the original status
188 ASSERT_EQ(movedHead
.Status(), 200);
190 ASSERT_EQ(movedHead
.GetHeader(nsHttp::Content_Type
, value
), NS_OK
);
191 ASSERT_EQ(value
, "text/plain"_ns
);
192 ASSERT_EQ(movedHead
.GetHeader(nsHttp::Content_Length
, value
), NS_OK
);
193 ASSERT_EQ(value
, "1408"_ns
);
195 // Check original object is in an unspecified state
196 ASSERT_EQ(originalHead
.GetHeader(nsHttp::Content_Type
, value
),
197 NS_ERROR_NOT_AVAILABLE
);
198 ASSERT_FALSE(originalHead
.HasHeader(nsHttp::Content_Type
));
199 ASSERT_FALSE(originalHead
.HasHeader(nsHttp::Content_Length
));
203 } // namespace mozilla