TestHttpResponseHead.cpp (8242B)
1 #include "gtest/gtest.h" 2 3 #include "chrome/common/ipc_message.h" 4 #include "mozilla/net/PHttpChannelParams.h" 5 #include "nsHttp.h" 6 #include "nsIPrefBranch.h" 7 #include "nsIPrefService.h" 8 #include "nsURLHelper.h" 9 10 namespace mozilla { 11 namespace net { 12 13 void AssertRoundTrips(const nsHttpResponseHead& aHead) { 14 { 15 // Assert it round-trips via IPC. 16 UniquePtr<IPC::Message> msg(new IPC::Message(MSG_ROUTING_NONE, 0)); 17 IPC::MessageWriter writer(*msg); 18 IPC::ParamTraits<nsHttpResponseHead>::Write(&writer, aHead); 19 20 nsHttpResponseHead deserializedHead; 21 IPC::MessageReader reader(*msg); 22 bool res = IPC::ParamTraits<mozilla::net::nsHttpResponseHead>::Read( 23 &reader, &deserializedHead); 24 ASSERT_TRUE(res); 25 ASSERT_EQ(aHead, deserializedHead); 26 } 27 28 { 29 // Assert it round-trips through copy-ctor. 30 nsHttpResponseHead copied(aHead); 31 ASSERT_EQ(aHead, copied); 32 } 33 34 { 35 // Assert it round-trips through operator= 36 nsHttpResponseHead copied; 37 copied = aHead; 38 // It is important that the below statement cannot be 39 // ASSERT_EQ(aHead, copied) to avoid potential lock-order inversion problem. 40 // See Bug 1829445 for more details 41 ASSERT_EQ(copied, aHead); 42 } 43 } 44 45 TEST(TestHttpResponseHead, Bug1636930) 46 { 47 nsHttpResponseHead head; 48 49 (void)head.ParseStatusLine("HTTP/1.1 200 OK"_ns); 50 (void)head.ParseHeaderLine("content-type: text/plain"_ns); 51 (void)head.ParseHeaderLine("etag: Just testing"_ns); 52 (void)head.ParseHeaderLine("cache-control: max-age=99999"_ns); 53 (void)head.ParseHeaderLine("accept-ranges: bytes"_ns); 54 (void)head.ParseHeaderLine("content-length: 1408"_ns); 55 (void)head.ParseHeaderLine("connection: close"_ns); 56 (void)head.ParseHeaderLine("server: httpd.js"_ns); 57 (void)head.ParseHeaderLine("date: Tue, 12 May 2020 09:24:23 GMT"_ns); 58 59 AssertRoundTrips(head); 60 } 61 62 TEST(TestHttpResponseHead, bug1649807) 63 { 64 nsHttpResponseHead head; 65 66 (void)head.ParseStatusLine("HTTP/1.1 200 OK"_ns); 67 (void)head.ParseHeaderLine("content-type: text/plain"_ns); 68 (void)head.ParseHeaderLine("etag: Just testing"_ns); 69 (void)head.ParseHeaderLine( 70 "cache-control: public, max-age=31536000, immutable"_ns); 71 (void)head.ParseHeaderLine("accept-ranges: bytes"_ns); 72 (void)head.ParseHeaderLine("content-length: 1408"_ns); 73 (void)head.ParseHeaderLine("connection: close"_ns); 74 (void)head.ParseHeaderLine("server: httpd.js"_ns); 75 (void)head.ParseHeaderLine("pragma: no-cache"_ns); 76 (void)head.ParseHeaderLine("date: Tue, 12 May 2020 09:24:23 GMT"_ns); 77 78 ASSERT_FALSE(head.NoCache()) 79 << "Cache-Control: immutable wins over Pragma: no-cache"; 80 AssertRoundTrips(head); 81 } 82 83 TEST(TestHttpResponseHead, bug1937766) 84 { 85 nsHttpResponseHead head; 86 87 (void)head.ParseStatusLine("HTTP/1.1 200 OK"_ns); 88 (void)head.ParseHeaderLine("content-type: text/plain"_ns); 89 (void)head.ParseHeaderLine("etag: Just testing"_ns); 90 (void)head.ParseHeaderLine("cache-control: age=99999"_ns); 91 (void)head.ParseHeaderLine("accept-ranges: bytes"_ns); 92 (void)head.ParseHeaderLine("content-length: 1408"_ns); 93 (void)head.ParseHeaderLine("connection: close"_ns); 94 (void)head.ParseHeaderLine("server: httpd.js"_ns); 95 (void)head.ParseHeaderLine("pragma: no-cache"_ns); 96 (void)head.ParseHeaderLine("date: Tue, 12 May 2020 09:24:23 GMT"_ns); 97 98 ASSERT_TRUE(head.NoCache()) 99 << "Pragma: no-cache wins over Cache-Control"; 100 AssertRoundTrips(head); 101 } 102 103 TEST(TestHttpResponseHead, bug1660200) 104 { 105 nsHttpResponseHead head; 106 107 (void)head.ParseStatusLine("HTTP/1.1 200 OK"_ns); 108 (void)head.ParseHeaderLine("content-type: text/plain"_ns); 109 (void)head.ParseHeaderLine("etag: Just testing"_ns); 110 (void)head.ParseHeaderLine("cache-control: no-cache"_ns); 111 (void)head.ParseHeaderLine("accept-ranges: bytes"_ns); 112 (void)head.ParseHeaderLine("content-length: 1408"_ns); 113 (void)head.ParseHeaderLine("connection: close"_ns); 114 (void)head.ParseHeaderLine("server: httpd.js"_ns); 115 (void)head.ParseHeaderLine("date: Tue, 12 May 2020 09:24:23 GMT"_ns); 116 117 AssertRoundTrips(head); 118 } 119 120 TEST(TestHttpResponseHead, bug1687903) 121 { 122 nsHttpResponseHead head; 123 124 nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); 125 126 nsresult expectation = NS_ERROR_PARSING_HTTP_STATUS_LINE; 127 128 ASSERT_EQ(expectation, head.ParseStatusLine("HTTP/1.1 "_ns)); 129 ASSERT_EQ(expectation, head.ParseStatusLine("HTTP/1.1 BLAH"_ns)); 130 ASSERT_EQ(expectation, head.ParseStatusLine("HTTP/1.1 1000 BOO"_ns)); 131 ASSERT_EQ(expectation, head.ParseStatusLine("HTTP/1.1 0200 BOO"_ns)); 132 ASSERT_EQ(expectation, head.ParseStatusLine("HTTP/1.1 60200 200"_ns)); 133 ASSERT_EQ(expectation, head.ParseStatusLine("HTTP/1.1 131072 HIOK"_ns)); 134 ASSERT_EQ(expectation, head.ParseStatusLine("HTTP/1.1 -200 OK"_ns)); 135 ASSERT_EQ(expectation, head.ParseStatusLine("HTTP/1.1 0x9 OK"_ns)); 136 ASSERT_EQ(expectation, head.ParseStatusLine("HTTP/1.1 C8 OK"_ns)); 137 } 138 139 TEST(TestHttpResponseHead, atoms) 140 { 141 // Test that the resolving the content-type atom returns the initial static 142 ASSERT_EQ(nsHttp::Content_Type, nsHttp::ResolveAtom("content-type"_ns)); 143 // Check that they're case insensitive 144 ASSERT_EQ(nsHttp::ResolveAtom("Content-Type"_ns), 145 nsHttp::ResolveAtom("content-type"_ns)); 146 // This string literal should be the backing of the atom when resolved first 147 auto header1 = "CustomHeaderXXX1"_ns; 148 auto atom1 = nsHttp::ResolveAtom(header1); 149 auto header2 = "customheaderxxx1"_ns; 150 auto atom2 = nsHttp::ResolveAtom(header2); 151 ASSERT_EQ(atom1, atom2); 152 ASSERT_EQ(atom1.get(), atom2.get()); 153 // Check that we get the expected pointer back. 154 ASSERT_EQ(atom2.get(), header1.BeginReading()); 155 } 156 157 TEST(ContentTypeParsing, CommentHandling1) 158 { 159 bool dummy; 160 const nsAutoCString val("text/html;charset=gbk("); 161 nsCString contentType; 162 nsCString contentCharset; 163 164 net_ParseContentType(val, contentType, contentCharset, &dummy); 165 166 ASSERT_TRUE(contentType.EqualsLiteral("text/html")); 167 ASSERT_TRUE(contentCharset.EqualsLiteral("gbk(")); 168 } 169 170 TEST(ContentTypeParsing, CommentHandling2) 171 { 172 bool dummy; 173 const nsAutoCString val("text/html;x=(;charset=gbk"); 174 nsCString contentType; 175 nsCString contentCharset; 176 177 net_ParseContentType(val, contentType, contentCharset, &dummy); 178 179 ASSERT_TRUE(contentType.EqualsLiteral("text/html")); 180 ASSERT_TRUE(contentCharset.EqualsLiteral("gbk")); 181 } 182 183 TEST(ContentTypeParsing, CommentHandling3) 184 { 185 bool dummy; 186 const nsAutoCString val("text/html;test=test;(;charset=gbk"); 187 nsCString contentType; 188 nsCString contentCharset; 189 190 net_ParseContentType(val, contentType, contentCharset, &dummy); 191 192 ASSERT_TRUE(contentType.EqualsLiteral("text/html")); 193 ASSERT_TRUE(contentCharset.EqualsLiteral("gbk")); 194 } 195 196 TEST(TestHttpResponseHead, MoveConstructor) 197 { 198 // Construct an initial response head 199 nsHttpResponseHead originalHead; 200 (void)originalHead.ParseStatusLine("HTTP/1.1 200 OK"_ns); 201 (void)originalHead.ParseHeaderLine("content-type: text/plain"_ns); 202 (void)originalHead.ParseHeaderLine("content-length: 1408"_ns); 203 204 // Move construct a new object from the initial one 205 nsHttpResponseHead movedHead(std::move(originalHead)); 206 207 // Ensure the moved head retains the original status 208 ASSERT_EQ(movedHead.Status(), 200); 209 nsCString value; 210 ASSERT_EQ(movedHead.GetHeader(nsHttp::Content_Type, value), NS_OK); 211 ASSERT_EQ(value, "text/plain"_ns); 212 ASSERT_EQ(movedHead.GetHeader(nsHttp::Content_Length, value), NS_OK); 213 ASSERT_EQ(value, "1408"_ns); 214 215 // Check original object is in an unspecified state 216 ASSERT_EQ(originalHead.GetHeader(nsHttp::Content_Type, value), 217 NS_ERROR_NOT_AVAILABLE); 218 ASSERT_FALSE(originalHead.HasHeader(nsHttp::Content_Type)); 219 ASSERT_FALSE(originalHead.HasHeader(nsHttp::Content_Length)); 220 } 221 222 TEST(TestHttpResponseHead, MultipleCacheControl) 223 { 224 nsHttpResponseHead originalHead; 225 (void)originalHead.ParseStatusLine("HTTP/1.1 200 OK"_ns); 226 (void)originalHead.ParseHeaderLine("content-type: text/plain"_ns); 227 (void)originalHead.ParseHeaderLine("content-length: 1408"_ns); 228 (void)originalHead.ParseHeaderLine("cache-control: no-cache"_ns); 229 (void)originalHead.ParseHeaderLine("cache-control: no-store"_ns); 230 231 ASSERT_EQ(originalHead.NoStore(), true); 232 ASSERT_EQ(originalHead.NoCache(), true); 233 } 234 235 } // namespace net 236 } // namespace mozilla