Skip to content

Commit

Permalink
Enable to overwrite default headers by command line options (#111)
Browse files Browse the repository at this point in the history
* add 'no-default-headers' flag
* amend test cases and docs
* Cleanup and refactor

---------

Co-authored-by: GollyTicker <golly.ticker@gmail.com>
  • Loading branch information
lyra95 and GollyTicker committed Mar 17, 2023
1 parent ad536ae commit 962eada
Show file tree
Hide file tree
Showing 43 changed files with 933 additions and 35 deletions.
4 changes: 2 additions & 2 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
test/results/*.txt text eol=lf
**.md text eol=lf
**.sh text eol=lf
**/*.md text eol=lf
**/**.sh text eol=lf
23 changes: 22 additions & 1 deletion EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,26 @@ will produce no output, exit with a non-zero exitcode and only show this error:
Error: Request was unsuccessful. Received response status code outside of 2XX. Got: HTTP/1.1 404 Not Found
```

**No Default Header**

Some headers use default values (e.g. `Content-Type: application/x-protobuf`). If you do not want to use these default values, use `--no-default-headers` flag (only work when using `--curl`).

```bash
$ docker run -v "$PWD/test/proto:/proto" --network host qaware/protocurl \
-i ..HappyDayRequest -o ..HappyDayResponse \
-u http://localhost:8080/happy-day/verify \
-d "date: { seconds: 1648044939}" \
--curl -n -H 'Content-Type: application/octet-stream'

=========================== Request Text =========================== >>>
date: {
seconds: 1648044939
}
=========================== Response Text =========================== <<<
formattedDate: "Wed, 23 Mar 2022 14:15:39 GMT"
```


**Verbose via -v**

```bash
Expand All @@ -170,6 +190,7 @@ Invoked with following default & parsed arguments:
"OutTextType": "text",
"DecodeRawResponse": false,
"DisplayBinaryAndHttp": true,
"NoDefaultHeaders": false,
"RequestHeaders": [
"Content-Type: application/x-protobuf"
],
Expand Down Expand Up @@ -413,7 +434,7 @@ Total curl args:
=========================== Response Headers =========================== <<<
HTTP/1.1 200 OK
Content-Type: application/x-protobuf
Date: Sat, 11 Jun 2022 11:15:35 GMT
Date: Fri, 17 Mar 2023 23:19:03 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 35
Expand Down
17 changes: 17 additions & 0 deletions doc/generate-docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,22 @@ $(docker run -v "$WORKING_DIR/test/proto:/proto" --network host protocurl \
escapeString "$EXAMPLE_4"
EXAMPLE_4="$ESCAPED"

# EXAMPLE_NO_DEFAULT_HEADER ============================
EXAMPLE_NO_DEFAULT_HEADER="\$ docker run -v \"\$PWD/test/proto:/proto\" --network host qaware/protocurl \\
-i ..HappyDayRequest -o ..HappyDayResponse \\
-u http://localhost:8080/happy-day/verify \\
-d \"date: { seconds: 1648044939}\" \\
--curl -n -H 'Content-Type: application/octet-stream'
$(docker run -v "$WORKING_DIR/test/proto:/proto" --network host protocurl \
-i ..HappyDayRequest -o ..HappyDayResponse \
-u http://localhost:8080/happy-day/verify \
-d "date: { seconds: 1648044939}" \
--curl -n -H'Content-Type: application/octet-stream')"

escapeString "$EXAMPLE_NO_DEFAULT_HEADER"
EXAMPLE_NO_DEFAULT_HEADER="$ESCAPED"

# replacements ============================
echo "$EXAMPLES_TEMPLATE" |
sed "s%___EXAMPLE_1___%$EXAMPLE_1%" |
Expand All @@ -182,6 +198,7 @@ echo "$EXAMPLES_TEMPLATE" |
sed "s%___EXAMPLE_OUTPUT_ONLY___%$EXAMPLE_OUTPUT_ONLY%" |
sed "s%___EXAMPLE_OUTPUT_ONLY_WITH_ERR_1___%$EXAMPLE_OUTPUT_ONLY_WITH_ERR_1%" |
sed "s%___EXAMPLE_OUTPUT_ONLY_WITH_ERR_2___%$EXAMPLE_OUTPUT_ONLY_WITH_ERR_2%" |
sed "s%___EXAMPLE_NO_DEFAULT_HEADER___%$EXAMPLE_NO_DEFAULT_HEADER%" |
sed "s%___EXAMPLE_4___%$EXAMPLE_4%" >EXAMPLES.md

normaliseOutput EXAMPLES.md
Expand Down
3 changes: 2 additions & 1 deletion doc/generated.usage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ It uses 'curl' from PATH. If none was found, it will fall back to an internal no
It uses a bundled 'protoc' (by default) which is used to parse the .proto files.
The bundle also includes the well-known Google Protobuf files necessary to create FileDescriptorSet payloads via 'protoc'.
If the bundled 'protoc' is used, then these .proto files are included. Otherwise .proto files from the system-wide include are used.
The Header 'Content-Type: application/x-protobuf' is set as a request header by default.
The Header 'Content-Type: application/x-protobuf' is set as a request header by default. (disable via -n)
When converting between binary and text, the encoding UTF-8 is always used.
When the correct response type is unknown or being debugged, omitting -o <response-type> will attempt to show the response in raw format.

Expand All @@ -29,6 +29,7 @@ Flags:
--in string Specifies, in which format the input -d should be interpreted in. 'text' (default) uses the Protobuf text format and 'json' uses JSON. The type is inferred as JSON if the first token is a '{'.
-F, --infer-files Infer the correct files containing the relevant protobuf messages. All proto files in the proto directory provided by -I will be used. If no -f <file> is provided, this -F is set and the files are inferred.
--no-curl Forces the use of the built-in internal http request instead of curl.
-n, --no-default-headers Default headers (e.g. "Content-Type") will not be passed to curl. Assumes --curl. Use "-n -H 'Content-Type: FooBar'" to override the default content type.
--out string Produces the output in the specified format. 'text' (default) produces Protobuf text format. 'json' produces dense JSON and 'json:pretty' produces pretty-printed JSON. The produced JSON always uses the original Protobuf field names instead of lowerCamelCasing them.
-I, --proto-dir string Uses the specified directory to find the proto-file. (default "/proto")
-f, --proto-file string Uses the specified file path to find the Protobuf definition of the message types within 'proto-dir' (relative file path).
Expand Down
9 changes: 9 additions & 0 deletions doc/template.EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@ will produce no output, exit with a non-zero exitcode and only show this error:
___EXAMPLE_OUTPUT_ONLY_WITH_ERR_2___
```

**No Default Header**

Some headers use default values (e.g. `Content-Type: application/x-protobuf`). If you do not want to use these default values, use `--no-default-headers` flag (only work when using `--curl`).

```bash
___EXAMPLE_NO_DEFAULT_HEADER___
```


**Verbose via -v**

```bash
Expand Down
5 changes: 4 additions & 1 deletion src/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ func intialiseFlags() {
"The format can be set explicitly via --in. See "+GithubRepositoryLink)
AssertSuccess(rootCmd.MarkFlagRequired("data-text"))

flags.BoolVarP(&CurrentConfig.NoDefaultHeaders, "no-default-headers", "n", false,
"Default headers (e.g. \"Content-Type\") will not be passed to curl. Assumes --curl. Use \"-n -H 'Content-Type: FooBar'\" to override the default content type.")

flags.StringArrayVarP(&CurrentConfig.RequestHeaders, "request-header", "H", []string{},
"Adds the `string` header to the invocation of cURL. This option is not supported when --no-curl is active. E.g. -H 'MyHeader: FooBar'.")

Expand Down Expand Up @@ -209,5 +212,5 @@ func propagateFlags() {
}

func PanicDueToUnsupportedHeadersWhenInternalHttp(headers []string) {
PanicWithMessage(fmt.Sprintf("Custom headers are not supported when using internal http. Please provide curl in path and avoid using --no-curl. Found headers: %+q", headers))
PanicWithMessage(fmt.Sprintf("Non-default or custom headers are not supported when using internal http. Please provide curl in path and avoid using --no-curl. Found headers: %+q", headers))
}
7 changes: 6 additions & 1 deletion src/httpRequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func invokeInternalHttpRequest(requestBinary []byte) ([]byte, string) {
fmt.Println("Invoking internal http request.")
}

if len(CurrentConfig.RequestHeaders) != 1 || CurrentConfig.RequestHeaders[0] != DefaultHeaders[0] {
if usingUnsupportedNonDefaultHeaders() {
PanicDueToUnsupportedHeadersWhenInternalHttp(CurrentConfig.RequestHeaders)
}

Expand All @@ -40,6 +40,11 @@ func invokeInternalHttpRequest(requestBinary []byte) ([]byte, string) {
return body, strings.TrimSpace(headersString)
}

func usingUnsupportedNonDefaultHeaders() bool {
usingNonDefaultHeaders := len(CurrentConfig.RequestHeaders) != 1 || CurrentConfig.RequestHeaders[0] != DefaultHeaders[0]
return CurrentConfig.NoDefaultHeaders || usingNonDefaultHeaders
}

func invokeCurlRequest(requestBinary []byte, curlPath string) ([]byte, string) {
if CurrentConfig.Verbose {
fmt.Println("Invoking curl http request.")
Expand Down
7 changes: 6 additions & 1 deletion src/protocurl.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type Config struct {
OutTextType OutTextType
DecodeRawResponse bool
DisplayBinaryAndHttp bool
NoDefaultHeaders bool
RequestHeaders []string
CustomCurlPath string
AdditionalCurlArgs string
Expand Down Expand Up @@ -65,7 +66,7 @@ var rootCmd = &cobra.Command{
"It uses a bundled '" + ProtocExecutableName + "' (by default) which is used to parse the .proto files.\n" +
"The bundle also includes the well-known Google Protobuf files necessary to create FileDescriptorSet payloads via '" + ProtocExecutableName + "'.\n" +
"If the bundled '" + ProtocExecutableName + "' is used, then these .proto files are included. Otherwise .proto files from the system-wide include are used.\n" +
"The Header 'Content-Type: application/x-protobuf' is set as a request header by default.\n" +
"The Header 'Content-Type: application/x-protobuf' is set as a request header by default. (disable via -n)\n" +
"When converting between binary and text, the encoding UTF-8 is always used.\n" +
"When the correct response type is unknown or being debugged, omitting -o <response-type> will attempt to show the response in raw format.\n\n" +
"Enhancements and bugs: " + EnhancementsAndBugsLink,
Expand Down Expand Up @@ -172,6 +173,10 @@ func properResponseTypeIfProvidedOrEmptyType() string {
}

func addDefaultHeaderArgument() {
if CurrentConfig.NoDefaultHeaders {
return
}

if CurrentConfig.Verbose {
fmt.Printf("Adding default header argument to request headers : %s\n", DefaultHeaders)
}
Expand Down
2 changes: 1 addition & 1 deletion test/results/additional-curl-args-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ includeReason: true
=========================== Response Headers =========================== <<<
HTTP/1.1 200 OK
Content-Type: application/x-protobuf
Date: Tue, 26 Apr 2022 22:34:28 GMT
Date: Fri, 17 Mar 2023 11:27:07 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 65
Expand Down
5 changes: 3 additions & 2 deletions test/results/additional-curl-args-verbose-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Invoked with following default & parsed arguments:
"OutTextType": "text",
"DecodeRawResponse": false,
"DisplayBinaryAndHttp": true,
"NoDefaultHeaders": false,
"RequestHeaders": [
"Content-Type: application/x-protobuf"
],
Expand Down Expand Up @@ -277,7 +278,7 @@ Total curl args:
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: application/x-protobuf
< Date: Mon, 16 May 2022 22:09:07 GMT
< Date: Fri, 17 Mar 2023 11:27:08 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
< Content-Length: 65
Expand All @@ -288,7 +289,7 @@ Total curl args:
=========================== Response Headers =========================== <<<
HTTP/1.1 200 OK
Content-Type: application/x-protobuf
Date: Mon, 16 May 2022 22:09:07 GMT
Date: Fri, 17 Mar 2023 11:27:08 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 65
Expand Down
2 changes: 1 addition & 1 deletion test/results/display-binary-and-headers-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ includeReason: true
=========================== Response Headers =========================== <<<
HTTP/1.1 200 OK
Content-Type: application/x-protobuf
Date: Tue, 26 Apr 2022 22:34:21 GMT
Date: Fri, 17 Mar 2023 11:27:06 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 65
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ HTTP/1.1 200 OK
Content-Length: 65
Connection: keep-alive
Content-Type: application/x-protobuf
Date: Tue, 26 Apr 2022 22:34:24 GMT
Date: Fri, 17 Mar 2023 11:27:07 GMT
Keep-Alive: timeout=5
=========================== Response Binary =========================== <<<
00000000 08 01 12 1c 54 68 75 72 73 64 61 79 20 69 73 20 |....Thursday is |
Expand Down
2 changes: 1 addition & 1 deletion test/results/echo-empty-with-curl-args-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ includeReason: true
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: application/x-protobuf
< Date: Tue, 26 Apr 2022 22:35:42 GMT
< Date: Fri, 17 Mar 2023 11:27:23 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
< Content-Length: 2
Expand Down
3 changes: 2 additions & 1 deletion test/results/far-future-json--v-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Invoked with following default & parsed arguments:
"OutTextType": "json",
"DecodeRawResponse": false,
"DisplayBinaryAndHttp": true,
"NoDefaultHeaders": false,
"RequestHeaders": [
"Content-Type: application/x-protobuf"
],
Expand Down Expand Up @@ -256,7 +257,7 @@ Total curl args:
=========================== Response Headers =========================== <<<
HTTP/1.1 200 OK
Content-Type: application/x-protobuf
Date: Mon, 16 May 2022 22:09:10 GMT
Date: Fri, 17 Mar 2023 11:27:12 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Content-Length: 63
Expand Down
3 changes: 2 additions & 1 deletion test/results/help-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ It uses 'curl' from PATH. If none was found, it will fall back to an internal no
It uses a bundled 'protoc' (by default) which is used to parse the .proto files.
The bundle also includes the well-known Google Protobuf files necessary to create FileDescriptorSet payloads via 'protoc'.
If the bundled 'protoc' is used, then these .proto files are included. Otherwise .proto files from the system-wide include are used.
The Header 'Content-Type: application/x-protobuf' is set as a request header by default.
The Header 'Content-Type: application/x-protobuf' is set as a request header by default. (disable via -n)
When converting between binary and text, the encoding UTF-8 is always used.
When the correct response type is unknown or being debugged, omitting -o <response-type> will attempt to show the response in raw format.

Expand All @@ -30,6 +30,7 @@ Flags:
--in string Specifies, in which format the input -d should be interpreted in. 'text' (default) uses the Protobuf text format and 'json' uses JSON. The type is inferred as JSON if the first token is a '{'.
-F, --infer-files Infer the correct files containing the relevant protobuf messages. All proto files in the proto directory provided by -I will be used. If no -f <file> is provided, this -F is set and the files are inferred.
--no-curl Forces the use of the built-in internal http request instead of curl.
-n, --no-default-headers Default headers (e.g. "Content-Type") will not be passed to curl. Assumes --curl. Use "-n -H 'Content-Type: FooBar'" to override the default content type.
--out string Produces the output in the specified format. 'text' (default) produces Protobuf text format. 'json' produces dense JSON and 'json:pretty' produces pretty-printed JSON. The produced JSON always uses the original Protobuf field names instead of lowerCamelCasing them.
-I, --proto-dir string Uses the specified directory to find the proto-file. (default "/proto")
-f, --proto-file string Uses the specified file path to find the Protobuf definition of the message types within 'proto-dir' (relative file path).
Expand Down
3 changes: 2 additions & 1 deletion test/results/help-missing-curl-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ It uses 'curl' from PATH. If none was found, it will fall back to an internal no
It uses a bundled 'protoc' (by default) which is used to parse the .proto files.
The bundle also includes the well-known Google Protobuf files necessary to create FileDescriptorSet payloads via 'protoc'.
If the bundled 'protoc' is used, then these .proto files are included. Otherwise .proto files from the system-wide include are used.
The Header 'Content-Type: application/x-protobuf' is set as a request header by default.
The Header 'Content-Type: application/x-protobuf' is set as a request header by default. (disable via -n)
When converting between binary and text, the encoding UTF-8 is always used.
When the correct response type is unknown or being debugged, omitting -o <response-type> will attempt to show the response in raw format.

Expand All @@ -30,6 +30,7 @@ Flags:
--in string Specifies, in which format the input -d should be interpreted in. 'text' (default) uses the Protobuf text format and 'json' uses JSON. The type is inferred as JSON if the first token is a '{'.
-F, --infer-files Infer the correct files containing the relevant protobuf messages. All proto files in the proto directory provided by -I will be used. If no -f <file> is provided, this -F is set and the files are inferred.
--no-curl Forces the use of the built-in internal http request instead of curl.
-n, --no-default-headers Default headers (e.g. "Content-Type") will not be passed to curl. Assumes --curl. Use "-n -H 'Content-Type: FooBar'" to override the default content type.
--out string Produces the output in the specified format. 'text' (default) produces Protobuf text format. 'json' produces dense JSON and 'json:pretty' produces pretty-printed JSON. The produced JSON always uses the original Protobuf field names instead of lowerCamelCasing them.
-I, --proto-dir string Uses the specified directory to find the proto-file. (default "/proto")
-f, --proto-file string Uses the specified file path to find the Protobuf definition of the message types within 'proto-dir' (relative file path).
Expand Down
3 changes: 2 additions & 1 deletion test/results/help-missing-curl-no-curl-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ It uses 'curl' from PATH. If none was found, it will fall back to an internal no
It uses a bundled 'protoc' (by default) which is used to parse the .proto files.
The bundle also includes the well-known Google Protobuf files necessary to create FileDescriptorSet payloads via 'protoc'.
If the bundled 'protoc' is used, then these .proto files are included. Otherwise .proto files from the system-wide include are used.
The Header 'Content-Type: application/x-protobuf' is set as a request header by default.
The Header 'Content-Type: application/x-protobuf' is set as a request header by default. (disable via -n)
When converting between binary and text, the encoding UTF-8 is always used.
When the correct response type is unknown or being debugged, omitting -o <response-type> will attempt to show the response in raw format.

Expand All @@ -30,6 +30,7 @@ Flags:
--in string Specifies, in which format the input -d should be interpreted in. 'text' (default) uses the Protobuf text format and 'json' uses JSON. The type is inferred as JSON if the first token is a '{'.
-F, --infer-files Infer the correct files containing the relevant protobuf messages. All proto files in the proto directory provided by -I will be used. If no -f <file> is provided, this -F is set and the files are inferred.
--no-curl Forces the use of the built-in internal http request instead of curl.
-n, --no-default-headers Default headers (e.g. "Content-Type") will not be passed to curl. Assumes --curl. Use "-n -H 'Content-Type: FooBar'" to override the default content type.
--out string Produces the output in the specified format. 'text' (default) produces Protobuf text format. 'json' produces dense JSON and 'json:pretty' produces pretty-printed JSON. The produced JSON always uses the original Protobuf field names instead of lowerCamelCasing them.
-I, --proto-dir string Uses the specified directory to find the proto-file. (default "/proto")
-f, --proto-file string Uses the specified file path to find the Protobuf definition of the message types within 'proto-dir' (relative file path).
Expand Down
Loading

0 comments on commit 962eada

Please sign in to comment.