aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/google.golang.org/api/transport/http/internal/propagation/http.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/google.golang.org/api/transport/http/internal/propagation/http.go')
-rw-r--r--vendor/google.golang.org/api/transport/http/internal/propagation/http.go96
1 files changed, 96 insertions, 0 deletions
diff --git a/vendor/google.golang.org/api/transport/http/internal/propagation/http.go b/vendor/google.golang.org/api/transport/http/internal/propagation/http.go
new file mode 100644
index 0000000..24b4f0d
--- /dev/null
+++ b/vendor/google.golang.org/api/transport/http/internal/propagation/http.go
@@ -0,0 +1,96 @@
1// Copyright 2018 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// +build go1.8
16
17// Package propagation implements X-Cloud-Trace-Context header propagation used
18// by Google Cloud products.
19package propagation
20
21import (
22 "encoding/binary"
23 "encoding/hex"
24 "fmt"
25 "net/http"
26 "strconv"
27 "strings"
28
29 "go.opencensus.io/trace"
30 "go.opencensus.io/trace/propagation"
31)
32
33const (
34 httpHeaderMaxSize = 200
35 httpHeader = `X-Cloud-Trace-Context`
36)
37
38var _ propagation.HTTPFormat = (*HTTPFormat)(nil)
39
40// HTTPFormat implements propagation.HTTPFormat to propagate
41// traces in HTTP headers for Google Cloud Platform and Stackdriver Trace.
42type HTTPFormat struct{}
43
44// SpanContextFromRequest extracts a Stackdriver Trace span context from incoming requests.
45func (f *HTTPFormat) SpanContextFromRequest(req *http.Request) (sc trace.SpanContext, ok bool) {
46 h := req.Header.Get(httpHeader)
47 // See https://cloud.google.com/trace/docs/faq for the header HTTPFormat.
48 // Return if the header is empty or missing, or if the header is unreasonably
49 // large, to avoid making unnecessary copies of a large string.
50 if h == "" || len(h) > httpHeaderMaxSize {
51 return trace.SpanContext{}, false
52 }
53
54 // Parse the trace id field.
55 slash := strings.Index(h, `/`)
56 if slash == -1 {
57 return trace.SpanContext{}, false
58 }
59 tid, h := h[:slash], h[slash+1:]
60
61 buf, err := hex.DecodeString(tid)
62 if err != nil {
63 return trace.SpanContext{}, false
64 }
65 copy(sc.TraceID[:], buf)
66
67 // Parse the span id field.
68 spanstr := h
69 semicolon := strings.Index(h, `;`)
70 if semicolon != -1 {
71 spanstr, h = h[:semicolon], h[semicolon+1:]
72 }
73 sid, err := strconv.ParseUint(spanstr, 10, 64)
74 if err != nil {
75 return trace.SpanContext{}, false
76 }
77 binary.BigEndian.PutUint64(sc.SpanID[:], sid)
78
79 // Parse the options field, options field is optional.
80 if !strings.HasPrefix(h, "o=") {
81 return sc, true
82 }
83 o, err := strconv.ParseUint(h[2:], 10, 64)
84 if err != nil {
85 return trace.SpanContext{}, false
86 }
87 sc.TraceOptions = trace.TraceOptions(o)
88 return sc, true
89}
90
91// SpanContextToRequest modifies the given request to include a Stackdriver Trace header.
92func (f *HTTPFormat) SpanContextToRequest(sc trace.SpanContext, req *http.Request) {
93 sid := binary.BigEndian.Uint64(sc.SpanID[:])
94 header := fmt.Sprintf("%s/%d;o=%d", hex.EncodeToString(sc.TraceID[:]), sid, int64(sc.TraceOptions))
95 req.Header.Set(httpHeader, header)
96}