Skip to content

Commit ee4db09

Browse files
weltekialexellis
authored andcommitted
Use same header format as curl for invoke command
Change the header flag to accept key value pairs separated by a colon. e.g. "key: value". The previous format is marked as deprecated but still supported. A warning is printed when it is used. Signed-off-by: Han Verstraete (OpenFaaS Ltd) <[email protected]>
1 parent 70eb80d commit ee4db09

File tree

2 files changed

+79
-19
lines changed

2 files changed

+79
-19
lines changed

commands/invoke.go

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,15 @@ func init() {
5858
}
5959

6060
var invokeCmd = &cobra.Command{
61-
Use: `invoke FUNCTION_NAME [--gateway GATEWAY_URL] [--content-type CONTENT_TYPE] [--query PARAM=VALUE] [--header PARAM=VALUE] [--method HTTP_METHOD]`,
61+
Use: `invoke FUNCTION_NAME [--gateway GATEWAY_URL] [--content-type CONTENT_TYPE] [--query KEY=VALUE] [--header "KEY: VALUE"] [--method HTTP_METHOD]`,
6262
Short: "Invoke an OpenFaaS function",
6363
Long: `Invokes an OpenFaaS function and reads from STDIN for the body of the request`,
64-
Example: ` faas-cli invoke echo --gateway https://host:port
64+
Example: ` faas-cli invoke printer --gateway https://host:port <<< "Hello"
6565
faas-cli invoke echo --gateway https://host:port --content-type application/json
6666
faas-cli invoke env --query repo=faas-cli --query org=openfaas
67-
faas-cli invoke env --header X-Ping-Url=http://request.bin/etc
68-
faas-cli invoke resize-img --async -H "X-Callback-Url=http://gateway:8080/function/send2slack" < image.png
69-
faas-cli invoke env -H X-Ping-Url=http://request.bin/etc
67+
faas-cli invoke env --header "X-Ping-Url: http://request.bin/etc"
68+
faas-cli invoke resize-img --async -H "X-Callback-Url: http://gateway:8080/function/send2slack" < image.png
69+
faas-cli invoke env -H X-Ping-Url: http://request.bin/etc
7070
faas-cli invoke flask --method GET --namespace dev
7171
faas-cli invoke env --sign X-GitHub-Event --key yoursecret`,
7272
RunE: runInvoke,
@@ -118,7 +118,10 @@ func runInvoke(cmd *cobra.Command, args []string) error {
118118
return err
119119
}
120120

121-
httpHeader.Set("Content-Type", contentType)
121+
if httpHeader.Get("Content-Type") == "" || cmd.Flag("content-type").Changed {
122+
httpHeader.Set("Content-Type", contentType)
123+
}
124+
122125
httpHeader.Set("User-Agent", fmt.Sprintf("faas-cli/%s (openfaas; %s; %s)", version.BuildVersion(), runtime.GOOS, runtime.GOARCH))
123126

124127
stat, _ := os.Stdin.Stat()
@@ -219,23 +222,49 @@ func missingSignFlag(header string, key string) bool {
219222
// parseHeaders parses header values from the header command flag
220223
func parseHeaders(headers []string) (http.Header, error) {
221224
httpHeader := http.Header{}
225+
warningShown := false
222226

223227
for _, header := range headers {
224-
headerVal := strings.SplitN(header, "=", 2)
225-
if len(headerVal) != 2 {
226-
return httpHeader, fmt.Errorf("the --header or -H flag must take the form of key=value")
227-
}
228+
// First try the preferred Key: Value format
229+
parts := strings.SplitN(header, ":", 2)
230+
if len(parts) == 2 {
231+
key := strings.TrimSpace(parts[0])
232+
if key == "" {
233+
return httpHeader, fmt.Errorf("the --header or -H flag must take the form of 'Key: Value' (empty key given)")
234+
}
228235

229-
key, value := headerVal[0], headerVal[1]
230-
if key == "" {
231-
return httpHeader, fmt.Errorf("the --header or -H flag must take the form of key=value (empty key given)")
236+
value := strings.TrimSpace(parts[1])
237+
if value == "" {
238+
return httpHeader, fmt.Errorf("the --header or -H flag must take the form of 'Key: Value' (empty value given)")
239+
}
240+
241+
httpHeader.Add(key, value)
242+
continue
232243
}
233244

234-
if value == "" {
235-
return httpHeader, fmt.Errorf("the --header or -H flag must take the form of key=value (empty value given)")
245+
// Fallback to deprecated key=value format
246+
parts = strings.SplitN(header, "=", 2)
247+
if len(parts) == 2 {
248+
key := parts[0]
249+
if key == "" {
250+
return httpHeader, fmt.Errorf("the --header or -H flag must take the form of 'Key: Value' or 'key=value' (empty key given)")
251+
}
252+
253+
value := parts[1]
254+
if value == "" {
255+
return httpHeader, fmt.Errorf("the --header or -H flag must take the form of 'Key: Value' or 'key=value' (empty value given)")
256+
}
257+
258+
// Print deprecation warning only once
259+
if !warningShown {
260+
fmt.Fprintf(os.Stderr, "Warning: Using deprecated 'key=value' format for headers. Please use 'Key: Value' format instead.\n")
261+
warningShown = true
262+
}
263+
httpHeader.Add(key, value)
264+
continue
236265
}
237266

238-
httpHeader.Add(key, value)
267+
return httpHeader, fmt.Errorf("the --header or -H flag must take the form of 'Key: Value' or 'key=value'")
239268
}
240269

241270
return httpHeader, nil

commands/invoke_test.go

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,19 +177,42 @@ func Test_parseHeaders_valid(t *testing.T) {
177177
}{
178178
{
179179
name: "Header with key-value pair as value",
180+
input: []string{`X-Hub-Signature: "sha1: "shashashaebaf43""`, "X-Hub-Signature-1: sha1: shashashaebaf43", "X-Hub-Signature-2:sha1:shashashaebaf43"},
181+
want: http.Header{
182+
"X-Hub-Signature": []string{`"sha1: "shashashaebaf43""`},
183+
"X-Hub-Signature-1": []string{"sha1: shashashaebaf43"},
184+
"X-Hub-Signature-2": []string{"sha1:shashashaebaf43"},
185+
},
186+
},
187+
{
188+
name: "Header with normal values",
189+
input: []string{`X-Hub-Signature: "shashashaebaf43"`, "X-Hub-Signature-1: shashashaebaf43", "X-Hub-Signature-2:shashashaebaf43"},
190+
want: http.Header{
191+
"X-Hub-Signature": []string{`"shashashaebaf43"`},
192+
"X-Hub-Signature-1": []string{"shashashaebaf43"},
193+
"X-Hub-Signature-2": []string{"shashashaebaf43"},
194+
},
195+
},
196+
{
197+
name: "Header with base64 string value",
198+
input: []string{`X-Hub-Signature: "shashashaebaf43="`},
199+
want: http.Header{"X-Hub-Signature": []string{`"shashashaebaf43="`}},
200+
},
201+
{
202+
name: "Deprecated header format with key-value pair as value",
180203
input: []string{`X-Hub-Signature="sha1="shashashaebaf43""`, "X-Hub-Signature-1=sha1=shashashaebaf43"},
181204
want: http.Header{
182205
"X-Hub-Signature": []string{`"sha1="shashashaebaf43""`},
183206
"X-Hub-Signature-1": []string{"sha1=shashashaebaf43"},
184207
},
185208
},
186209
{
187-
name: "Header with normal values",
210+
name: "Deprecated header format with normal values",
188211
input: []string{`X-Hub-Signature="shashashaebaf43"`, "X-Hub-Signature-1=shashashaebaf43"},
189212
want: http.Header{"X-Hub-Signature": []string{`"shashashaebaf43"`}, "X-Hub-Signature-1": []string{"shashashaebaf43"}},
190213
},
191214
{
192-
name: "Header with base64 string value",
215+
name: "Deprecated header format with base64 string value",
193216
input: []string{`X-Hub-Signature="shashashaebaf43="`},
194217
want: http.Header{"X-Hub-Signature": []string{`"shashashaebaf43="`}},
195218
},
@@ -221,10 +244,18 @@ func Test_parseHeaders_invalid(t *testing.T) {
221244
},
222245
{
223246
name: "Empty header key",
224-
input: []string{"=shashashaebaf43"},
247+
input: []string{":shashashaebaf43"},
225248
},
226249
{
227250
name: "Empty header value",
251+
input: []string{"X-Hub-Signature:"},
252+
},
253+
{
254+
name: "Deprecated empty header key",
255+
input: []string{"=shashashaebaf43"},
256+
},
257+
{
258+
name: "Deprecated empty header value",
228259
input: []string{"X-Hub-Signature="},
229260
},
230261
}

0 commit comments

Comments
 (0)