Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/netwerk/protocol/http/nsServerTiming.cpp
Line
Count
Source (jump to first uncovered line)
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
NS_IMPL_ISUPPORTS(nsServerTiming, nsIServerTiming)
10
11
NS_IMETHODIMP
12
nsServerTiming::GetName(nsACString &aName)
13
0
{
14
0
  aName.Assign(mName);
15
0
  return NS_OK;
16
0
}
17
18
NS_IMETHODIMP
19
nsServerTiming::GetDuration(double *aDuration)
20
0
{
21
0
  *aDuration = mDuration;
22
0
  return NS_OK;
23
0
}
24
25
NS_IMETHODIMP
26
nsServerTiming::GetDescription(nsACString &aDescription)
27
0
{
28
0
  aDescription.Assign(mDescription);
29
0
  return NS_OK;
30
0
}
31
32
namespace mozilla {
33
namespace net {
34
35
static double
36
ParseDouble(const nsACString& aString)
37
0
{
38
0
  nsresult rv;
39
0
  double val = PromiseFlatCString(aString).ToDouble(&rv);
40
0
  return NS_FAILED(rv) ? 0.0f : val;
41
0
}
42
43
void
44
ServerTimingParser::Parse()
45
0
{
46
0
  // https://w3c.github.io/server-timing/#the-server-timing-header-field
47
0
  // Server-Timing             = #server-timing-metric
48
0
  // server-timing-metric      = metric-name *( OWS ";" OWS server-timing-param )
49
0
  // metric-name               = token
50
0
  // server-timing-param       = server-timing-param-name OWS "=" OWS server-timing-param-value
51
0
  // server-timing-param-name  = token
52
0
  // server-timing-param-value = token / quoted-string
53
0
54
0
  ParsedHeaderValueListList parsedHeader(mValue, false);
55
0
  for (uint32_t index = 0; index < parsedHeader.mValues.Length(); ++index) {
56
0
    if (parsedHeader.mValues[index].mValues.IsEmpty()) {
57
0
      continue;
58
0
    }
59
0
60
0
    // According to spec, the first ParsedHeaderPair's name is metric-name.
61
0
    RefPtr<nsServerTiming> timingHeader = new nsServerTiming();
62
0
    mServerTimingHeaders.AppendElement(timingHeader);
63
0
    timingHeader->SetName(parsedHeader.mValues[index].mValues[0].mName);
64
0
65
0
    if (parsedHeader.mValues[index].mValues.Length() == 1) {
66
0
      continue;
67
0
    }
68
0
69
0
    // Try to find duration and description from the rest ParsedHeaderPairs.
70
0
    bool foundDuration = false;
71
0
    bool foundDescription = false;
72
0
    for (uint32_t pairIndex = 1;
73
0
         pairIndex < parsedHeader.mValues[index].mValues.Length();
74
0
         ++pairIndex) {
75
0
      nsDependentCSubstring &currentName =
76
0
        parsedHeader.mValues[index].mValues[pairIndex].mName;
77
0
      nsDependentCSubstring &currentValue =
78
0
        parsedHeader.mValues[index].mValues[pairIndex].mValue;
79
0
80
0
      // We should only take the value from the first
81
0
      // occurrence of server-timing-param-name ("dur" and "desc").
82
0
      // This is true whether or not the value makes any sense (or, indeed, if
83
0
      // there even is a value).
84
0
      if (currentName.LowerCaseEqualsASCII("dur") &&
85
0
          !foundDuration) {
86
0
        if (currentValue.BeginReading()) {
87
0
          timingHeader->SetDuration(ParseDouble(currentValue));
88
0
        } else {
89
0
          timingHeader->SetDuration(0.0);
90
0
        }
91
0
        foundDuration = true;
92
0
      } else if (currentName.LowerCaseEqualsASCII("desc") &&
93
0
                 !foundDescription) {
94
0
        if (!currentValue.IsEmpty()) {
95
0
          timingHeader->SetDescription(currentValue);
96
0
        } else {
97
0
          timingHeader->SetDescription(EmptyCString());
98
0
        }
99
0
        foundDescription = true;
100
0
      }
101
0
102
0
      if (foundDuration && foundDescription) {
103
0
        break;
104
0
      }
105
0
    }
106
0
  }
107
0
}
108
109
nsTArray<nsCOMPtr<nsIServerTiming>>&&
110
ServerTimingParser::TakeServerTimingHeaders()
111
0
{
112
0
  return std::move(mServerTimingHeaders);
113
0
}
114
115
} // namespace net
116
} // namespace mozilla