tor-browser

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

nsServerTiming.cpp (3608B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "nsServerTiming.h"
      8 
      9 #include "nsHttp.h"
     10 
     11 NS_IMPL_ISUPPORTS(nsServerTiming, nsIServerTiming)
     12 
     13 NS_IMETHODIMP
     14 nsServerTiming::GetName(nsACString& aName) {
     15  aName.Assign(mName);
     16  return NS_OK;
     17 }
     18 
     19 NS_IMETHODIMP
     20 nsServerTiming::GetDuration(double* aDuration) {
     21  *aDuration = mDuration;
     22  return NS_OK;
     23 }
     24 
     25 NS_IMETHODIMP
     26 nsServerTiming::GetDescription(nsACString& aDescription) {
     27  aDescription.Assign(mDescription);
     28  return NS_OK;
     29 }
     30 
     31 namespace mozilla {
     32 namespace net {
     33 
     34 static double ParseDouble(const nsACString& aString) {
     35  nsresult rv;
     36  double val = PromiseFlatCString(aString).ToDouble(&rv);
     37  return NS_FAILED(rv) ? 0.0f : val;
     38 }
     39 
     40 void ServerTimingParser::Parse() {
     41  // https://w3c.github.io/server-timing/#the-server-timing-header-field
     42  // Server-Timing             = #server-timing-metric
     43  // server-timing-metric      = metric-name *( OWS ";" OWS server-timing-param
     44  // ) metric-name               = token server-timing-param       =
     45  // server-timing-param-name OWS "=" OWS
     46  //                             server-timing-param-value
     47  // server-timing-param-name  = token
     48  // server-timing-param-value = token / quoted-string
     49 
     50  ParsedHeaderValueListList parsedHeader(mValue, false);
     51  for (uint32_t index = 0; index < parsedHeader.mValues.Length(); ++index) {
     52    if (parsedHeader.mValues[index].mValues.IsEmpty()) {
     53      continue;
     54    }
     55 
     56    // According to spec, the first ParsedHeaderPair's name is metric-name.
     57    RefPtr<nsServerTiming> timingHeader = new nsServerTiming();
     58    mServerTimingHeaders.AppendElement(timingHeader);
     59    timingHeader->SetName(parsedHeader.mValues[index].mValues[0].mName);
     60 
     61    if (parsedHeader.mValues[index].mValues.Length() == 1) {
     62      continue;
     63    }
     64 
     65    // Try to find duration and description from the rest ParsedHeaderPairs.
     66    bool foundDuration = false;
     67    bool foundDescription = false;
     68    for (uint32_t pairIndex = 1;
     69         pairIndex < parsedHeader.mValues[index].mValues.Length();
     70         ++pairIndex) {
     71      nsDependentCSubstring& currentName =
     72          parsedHeader.mValues[index].mValues[pairIndex].mName;
     73      nsDependentCSubstring& currentValue =
     74          parsedHeader.mValues[index].mValues[pairIndex].mValue;
     75 
     76      // We should only take the value from the first
     77      // occurrence of server-timing-param-name ("dur" and "desc").
     78      // This is true whether or not the value makes any sense (or, indeed, if
     79      // there even is a value).
     80      if (currentName.LowerCaseEqualsASCII("dur") && !foundDuration) {
     81        if (currentValue.BeginReading()) {
     82          timingHeader->SetDuration(ParseDouble(currentValue));
     83        } else {
     84          timingHeader->SetDuration(0.0);
     85        }
     86        foundDuration = true;
     87      } else if (currentName.LowerCaseEqualsASCII("desc") &&
     88                 !foundDescription) {
     89        if (!currentValue.IsEmpty()) {
     90          timingHeader->SetDescription(currentValue);
     91        } else {
     92          timingHeader->SetDescription(""_ns);
     93        }
     94        foundDescription = true;
     95      }
     96 
     97      if (foundDuration && foundDescription) {
     98        break;
     99      }
    100    }
    101  }
    102 }
    103 
    104 nsTArray<nsCOMPtr<nsIServerTiming>>&&
    105 ServerTimingParser::TakeServerTimingHeaders() {
    106  return std::move(mServerTimingHeaders);
    107 }
    108 
    109 }  // namespace net
    110 }  // namespace mozilla