explain how -output-curl-string works in comments to avoid confusion (#28576)

This commit is contained in:
Josh Black
2024-10-04 11:14:21 -07:00
committed by GitHub
parent 6a145af82a
commit d1355cb98f
3 changed files with 16 additions and 1 deletions

View File

@@ -1467,6 +1467,12 @@ START:
} }
if outputCurlString { if outputCurlString {
// Note that although we're building this up here and returning it as an error object, the Error()
// interface method on it only gets called in a context where the actual string returned from that
// method is irrelevant, because it gets swallowed by an error buffer that's never output to the user.
// That's on purpose, not a bug, because in this case, OutputStringError is not really an _error_, per se.
// It's just a way of aborting the control flow so that requests don't actually execute, and instead,
// we can detect what's happened back in the CLI machinery and show the actual curl string to the user.
LastOutputStringError = &OutputStringError{ LastOutputStringError = &OutputStringError{
Request: req, Request: req,
TLSSkipVerify: c.config.HttpClient.Transport.(*http.Transport).TLSClientConfig.InsecureSkipVerify, TLSSkipVerify: c.config.HttpClient.Transport.(*http.Transport).TLSClientConfig.InsecureSkipVerify,

View File

@@ -8,7 +8,7 @@ import (
"net/http" "net/http"
"strings" "strings"
retryablehttp "github.com/hashicorp/go-retryablehttp" "github.com/hashicorp/go-retryablehttp"
) )
const ( const (
@@ -25,6 +25,10 @@ type OutputStringError struct {
finalCurlString string finalCurlString string
} }
// Error is here so that we can return this struct as an error from client.rawRequestWithContext(). Note that
// the ErrOutputStringRequest constant is never actually used and is completely irrelevant to how this all functions.
// We could've just as easily returned an empty string. What matters is the machinery that happens before then where
// the curl string is built. So yes, this is confusing, but yes, this is also on purpose, and it is not incorrect.
func (d *OutputStringError) Error() string { func (d *OutputStringError) Error() string {
if d.finalCurlString == "" { if d.finalCurlString == "" {
cs, err := d.buildCurlString() cs, err := d.buildCurlString()

View File

@@ -186,6 +186,8 @@ func RunCustom(args []string, runOpts *RunOptions) int {
runOpts.Stderr = colorable.NewNonColorable(runOpts.Stderr) runOpts.Stderr = colorable.NewNonColorable(runOpts.Stderr)
} }
// This bytes.Buffer override of the uiErrWriter is why we don't see errors printed to the screen
// when running commands with e.g. -output-curl-string
uiErrWriter := runOpts.Stderr uiErrWriter := runOpts.Stderr
if outputCurlString || outputPolicy { if outputCurlString || outputPolicy {
uiErrWriter = &bytes.Buffer{} uiErrWriter = &bytes.Buffer{}
@@ -318,6 +320,9 @@ func generateCurlString(exitCode int, runOpts *RunOptions, preParsingErrBuf *byt
return 1 return 1
} }
// When we actually return from client.rawRequestWithContext(), this value should be set to the OutputStringError
// that contains the data/context required to output the actual string, so it's doubtful this chunk of code will
// ever run, but I'm guessing it's a defense in depth thing.
if api.LastOutputStringError == nil { if api.LastOutputStringError == nil {
if exitCode == 127 { if exitCode == 127 {
// Usage, just pass it through // Usage, just pass it through