tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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