Skip to content

Commit c649e81

Browse files
committed
Fix handling of ServerTiming quoting.
1 parent f435248 commit c649e81

File tree

2 files changed

+27
-11
lines changed

2 files changed

+27
-11
lines changed

lib/protocol/http/header/server_timing.rb

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ class ServerTiming < Split
2626
ParseError = Class.new(Error)
2727

2828
# https://www.w3.org/TR/server-timing/
29-
METRIC = /\A(?<name>[a-zA-Z0-9][a-zA-Z0-9_\-]*)(;(?<params>.*))?\z/
30-
PARAM = /(?<key>dur|desc)=(?<value>[^;,]+|"[^"]*")/
29+
METRIC = /\A(?<name>[a-zA-Z0-9][a-zA-Z0-9_\-]*)(;(?<parameters>.*))?\z/
30+
PARAMETER = /(?<key>dur|desc)=((?<value>#{TOKEN})|(?<quoted_value>#{QUOTED_STRING}))/
3131

3232
# A single metric in the Server-Timing header.
3333
Metric = Struct.new(:name, :duration, :description) do
@@ -58,22 +58,19 @@ def metrics
5858
self.map do |value|
5959
if match = value.match(METRIC)
6060
name = match[:name]
61-
params = match[:params] || ""
61+
parameters = match[:parameters] || ""
6262

6363
duration = nil
6464
description = nil
6565

66-
params.scan(PARAM) do |key, param_value|
66+
parameters.scan(PARAMETER) do |key, value, quoted_value|
67+
value = QuotedString.unquote(quoted_value) if quoted_value
68+
6769
case key
6870
when "dur"
69-
duration = param_value.to_f
71+
duration = value.to_f
7072
when "desc"
71-
# Remove quotes if present
72-
if param_value.start_with?('"') && param_value.end_with?('"')
73-
description = param_value[1..-2]
74-
else
75-
description = param_value
76-
end
73+
description = value
7774
end
7875
end
7976

test/protocol/http/header/server_timing.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@
3535
end
3636
end
3737

38+
with 'db;dur="53.2"' do
39+
it "can parse metric with quoted duration" do
40+
metrics = header.metrics
41+
expect(metrics.size).to be == 1
42+
expect(metrics.first.name).to be == "db"
43+
expect(metrics.first.duration).to be == 53.2
44+
expect(metrics.first.description).to be_nil
45+
end
46+
end
47+
3848
with 'cache;desc="Redis lookup"' do
3949
it "can parse metric with description" do
4050
metrics = header.metrics
@@ -54,6 +64,15 @@
5464
end
5565
end
5666

67+
with 'app;dur="12.7";desc="Application logic"' do
68+
it "can parse metric with quoted duration and quoted description" do
69+
metrics = header.metrics
70+
expect(metrics.first.name).to be == "app"
71+
expect(metrics.first.duration).to be == 12.7
72+
expect(metrics.first.description).to be == "Application logic"
73+
end
74+
end
75+
5776
with "db;dur=45.3, app;dur=12.7;desc=\"Application logic\", cache;desc=\"Cache miss\"" do
5877
it "can parse multiple metrics" do
5978
metrics = header.metrics

0 commit comments

Comments
 (0)