Skip to content

Commit

Permalink
Add ability to trace CloudAPI HTTP requests (#180)
Browse files Browse the repository at this point in the history
  • Loading branch information
twhiteman authored May 5, 2020
1 parent 536b709 commit 06eadae
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
## Unreleased

## 1.8.1 (May 4 2020)

- Add ability to trace CloudAPI HTTP requests [#180]. You can set the
TRITON_TRACE_HTTP environment variable to have the CloudAPI HTTP requests and
responses be printed to stderr.

## 1.8.0 (April 27 2020)

- Update Triton acceptance tests to work with any Triton [#178]
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ Additionally, you may set these optional environment variables:
is set, the PrivateKeySigner (see above) will be used - if not the
SSHAgentSigner will be used. You can also set `TRITON_USER` to run the tests
against an account other than the main Triton account.
- `TRITON_TRACE_HTTP` - when set this will print the HTTP requests and responses
to stderr.
- `TRITON_VERBOSE_TESTS` - turns on extra logging for test runs

### Example Run
Expand Down
25 changes: 25 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ import (
"net"
"net/http"
"net/url"
"os"
"regexp"
"strings"
"time"

triton "github.com/joyent/triton-go"
"github.com/joyent/triton-go/authentication"
"github.com/joyent/triton-go/errors"
tritonutils "github.com/joyent/triton-go/utils"
pkgerrors "github.com/pkg/errors"
)

Expand All @@ -46,6 +48,9 @@ var (

jpcFormatURL = "https://tsg.%s.svc.joyent.zone"
spcFormatURL = "https://tsg.%s.svc.samsungcloud.zone"

tritonTransportHttpTraceChecked = false
tritonTransportHttpTraceEnabled = false
)

// Client represents a connection to the Triton Compute or Object Storage APIs.
Expand All @@ -72,6 +77,21 @@ func isPrivateInstall(url string) bool {
return true
}

func wrapTritonTransport(in http.RoundTripper) http.RoundTripper {
if tritonTransportHttpTraceChecked == false {
tritonTransportHttpTraceChecked = true
if os.Getenv("TRITON_TRACE_HTTP") != "" {
tritonTransportHttpTraceEnabled = true
}
}

if tritonTransportHttpTraceEnabled {
return tritonutils.TraceRoundTripper(in)
}

return in
}

// parseDC parses out the data center commonly found in Triton URLs. Returns an
// error if the Triton URL does not include a known data center name, in which
// case a URL override (TRITON_TSG_URL) must be provided.
Expand Down Expand Up @@ -158,6 +178,9 @@ func New(tritonURL string, mantaURL string, accountName string, signers ...authe
AccountName: accountName,
}

// Allow wrapping of the HTTP Transport.
newClient.HTTPClient.Transport = wrapTritonTransport(newClient.HTTPClient.Transport)

// Default to constructing an SSHAgentSigner if there are no other signers
// passed into NewClient and there's an TRITON_KEY_ID and SSH_AUTH_SOCK
// available in the user's environ(7).
Expand Down Expand Up @@ -202,6 +225,8 @@ func (c *Client) InsecureSkipTLSVerify() {
}

c.HTTPClient.Transport = httpTransport(true)
// Allow wrapping of the HTTP Transport.
c.HTTPClient.Transport = wrapTritonTransport(c.HTTPClient.Transport)
}

// httpTransport is responsible for setting up our HTTP client's transport
Expand Down
64 changes: 64 additions & 0 deletions utils/http_debugging.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// Copyright 2020 Joyent, Inc.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

package utils

import (
"fmt"
"io"
"net/http"
"net/http/httputil"
"os"
)

// This file is used for tracing HTTP requests (trace).
//
// All HTTP requests and responses through this transport will be printed to
// stderr.

// TraceRoundTripper to wrap a HTTP Transport.
func TraceRoundTripper(in http.RoundTripper) http.RoundTripper {
return &traceRoundTripper{inner: in, logger: os.Stderr}
}

type traceRoundTripper struct {
inner http.RoundTripper
logger io.Writer
}

func (d *traceRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
d.dumpRequest(req)
res, err := d.inner.RoundTrip(req)
d.dumpResponse(res)
return res, err
}

func (d *traceRoundTripper) dumpRequest(r *http.Request) {
dump, err := httputil.DumpRequestOut(r, true)
if err != nil {
fmt.Fprintf(d.logger, "\n\tERROR dumping: %v\n", err)
return
}
d.dump("REQUEST", dump)
}

func (d *traceRoundTripper) dumpResponse(r *http.Response) {
dump, err := httputil.DumpResponse(r, true)
if err != nil {
fmt.Fprintf(d.logger, "\n\tERROR dumping: %v\n", err)
return
}
d.dump("RESPONSE", dump)
}

func (d *traceRoundTripper) dump(label string, dump []byte) {
fmt.Fprintf(d.logger, "\n%s:\n--\n%s\n", label, string(dump))
if label == "RESPONSE" {
fmt.Fprintf(d.logger, "\n")
}
}
2 changes: 1 addition & 1 deletion version.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (

// Version represents main version number of the current release
// of the Triton-go SDK.
const Version = "1.8.0"
const Version = "1.8.1"

// Prerelease adds a pre-release marker to the version.
//
Expand Down

0 comments on commit 06eadae

Please sign in to comment.