about summary refs log tree commit diff
path: root/third_party/overlays/patches/evans-add-support-for-bytes-as-base64.patch
blob: 1c4e67cc40a8713820807018b18d1d46b406d174 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
From f3e26c276256cb053de94725c10fecf243f11a68 Mon Sep 17 00:00:00 2001
From: Florian Klink <flokli@flokli.de>
Date: Sat, 26 Nov 2022 12:16:53 +0000
Subject: [PATCH] Add support for --bytes-as-base64

This allows entering bytes as a base64-encoded string, using the standard
encoding.
---
 README.md                                           |  6 ++++++
 .../fixtures/teste2e_repl-call_--help.golden        |  3 ++-
 fill/filler.go                                      |  2 ++
 fill/proto/interactive_filler.go                    |  8 +++++++-
 repl/commands.go                                    | 13 ++++++++++---
 usecase/call_rpc.go                                 |  7 ++++---
 6 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/README.md b/README.md
index 0f5932d..c02bf00 100644
--- a/README.md
+++ b/README.md
@@ -279,6 +279,12 @@ data (TYPE_BYTES) => \u65e5\u672c\u8a9e
 }
 ```
 
+Or add the flag `--bytes-as-base64` to pass bytes as a base64-encoded string
+```
+> call UnaryBytes --bytes-as-base64
+data (TYPE_BYTES) => SGVsbG8gV29ybGQh
+```
+
 Or add the flag `--bytes-from-file` to read bytes from the provided relative path
 ```
 > call UnaryBytes --bytes-from-file
diff --git a/e2e/testdata/fixtures/teste2e_repl-call_--help.golden b/e2e/testdata/fixtures/teste2e_repl-call_--help.golden
index 3fb24b3..e9b83e1 100644
--- a/e2e/testdata/fixtures/teste2e_repl-call_--help.golden
+++ b/e2e/testdata/fixtures/teste2e_repl-call_--help.golden
@@ -2,7 +2,8 @@ usage: call <method name>
 
 Options:
       --add-repeated-manually   prompt asks whether to add a value if it encountered to a repeated field
-      --bytes-from-file         interpret TYPE_BYTES input as a relative path to a file
+      --bytes-as-base64         interpret TYPE_BYTES input as base64-encoded string (mutually exclusive with --bytes-from-file)
+      --bytes-from-file         interpret TYPE_BYTES input as a relative path to a file (mutually exclusive with --bytes-as-base64)
       --dig-manually            prompt asks whether to dig down if it encountered to a message field
       --emit-defaults           render fields with default values
       --enrich                  enrich response output includes header, message, trailer and status
diff --git a/fill/filler.go b/fill/filler.go
index c53a62d..e0a96b9 100644
--- a/fill/filler.go
+++ b/fill/filler.go
@@ -22,6 +22,8 @@ type Filler interface {
 type InteractiveFillerOpts struct {
 	// DigManually is true, Fill asks whether to dig down if it encountered to a message field.
 	DigManually,
+	// BytesAsBase64 is true, Fill will interpret input as base64-encoded string
+	BytesAsBase64,
 	// BytesFromFile is true, Fill will read the contents of the file from the provided relative path.
 	BytesFromFile,
 	// AddRepeatedManually is true, Fill asks whether to add a repeated field value
diff --git a/fill/proto/interactive_filler.go b/fill/proto/interactive_filler.go
index fda0f8d..9b0d18c 100644
--- a/fill/proto/interactive_filler.go
+++ b/fill/proto/interactive_filler.go
@@ -1,6 +1,7 @@
 package proto
 
 import (
+	"encoding/base64"
 	"fmt"
 	"io"
 	"io/ioutil"
@@ -201,7 +202,12 @@ func (r *resolver) resolveField(f *desc.FieldDescriptor) error {
 		// So, we need to call strconv.Unquote to interpret backslashes as an escape sequence.
 		case descriptorpb.FieldDescriptorProto_TYPE_BYTES:
 			converter = func(v string) (interface{}, error) {
-				if r.opts.BytesFromFile {
+				if r.opts.BytesAsBase64 {
+					b, err := base64.StdEncoding.DecodeString(v)
+					if err == nil {
+						return b, nil
+					}
+				} else if r.opts.BytesFromFile {
 					b, err := ioutil.ReadFile(v)
 					if err == nil {
 						return b, nil
diff --git a/repl/commands.go b/repl/commands.go
index 6ba677e..a203ab9 100644
--- a/repl/commands.go
+++ b/repl/commands.go
@@ -155,7 +155,7 @@ func (c *showCommand) Run(w io.Writer, args []string) error {
 }
 
 type callCommand struct {
-	enrich, digManually, bytesFromFile, emitDefaults, repeatCall, addRepeatedManually bool
+	enrich, digManually, bytesAsBase64, bytesFromFile, emitDefaults, repeatCall, addRepeatedManually bool
 }
 
 func (c *callCommand) FlagSet() (*pflag.FlagSet, bool) {
@@ -163,7 +163,8 @@ func (c *callCommand) FlagSet() (*pflag.FlagSet, bool) {
 	fs.Usage = func() {} // Disable help output when an error occurred.
 	fs.BoolVar(&c.enrich, "enrich", false, "enrich response output includes header, message, trailer and status")
 	fs.BoolVar(&c.digManually, "dig-manually", false, "prompt asks whether to dig down if it encountered to a message field")
-	fs.BoolVar(&c.bytesFromFile, "bytes-from-file", false, "interpret TYPE_BYTES input as a relative path to a file")
+	fs.BoolVar(&c.bytesAsBase64, "bytes-as-base64", false, "interpret TYPE_BYTES input as base64-encoded string (mutually exclusive with --bytes-from-file)")
+	fs.BoolVar(&c.bytesFromFile, "bytes-from-file", false, "interpret TYPE_BYTES input as a relative path to a file (mutually exclusive with --bytes-as-base64)")
 	fs.BoolVar(&c.emitDefaults, "emit-defaults", false, "render fields with default values")
 	fs.BoolVarP(&c.repeatCall, "repeat", "r", false, "repeat previous unary or server streaming request (if exists)")
 	fs.BoolVar(&c.addRepeatedManually, "add-repeated-manually", false, "prompt asks whether to add a value if it encountered to a repeated field")
@@ -199,9 +200,15 @@ func (c *callCommand) Run(w io.Writer, args []string) error {
 		},
 	)
 
+	// Ensure bytesAsBase64 and bytesFromFile are not both set
+	// pflag doesn't suppport mutually exclusive flags (https://github.com/spf13/pflag/issues/270)
+	if c.bytesAsBase64 && c.bytesFromFile {
+		return errors.New("only one of --bytes-as-base64 or --bytes-from-file can be specified")
+	}
+
 	// here we create the request context
 	// we also add the call command flags here
-	err := usecase.CallRPCInteractively(context.Background(), w, args[0], c.digManually, c.bytesFromFile, c.repeatCall, c.addRepeatedManually)
+	err := usecase.CallRPCInteractively(context.Background(), w, args[0], c.digManually, c.bytesAsBase64, c.bytesFromFile, c.repeatCall, c.addRepeatedManually)
 	if errors.Is(err, io.EOF) {
 		return errors.New("inputting canceled")
 	}
diff --git a/usecase/call_rpc.go b/usecase/call_rpc.go
index e5f9415..48e795e 100644
--- a/usecase/call_rpc.go
+++ b/usecase/call_rpc.go
@@ -478,15 +478,16 @@ func (f *interactiveFiller) Fill(v interface{}) error {
 	return f.fillFunc(v)
 }
 
-func CallRPCInteractively(ctx context.Context, w io.Writer, rpcName string, digManually, bytesFromFile, rerunPrevious, addRepeatedManually bool) error {
-	return dm.CallRPCInteractively(ctx, w, rpcName, digManually, bytesFromFile, rerunPrevious, addRepeatedManually)
+func CallRPCInteractively(ctx context.Context, w io.Writer, rpcName string, digManually, bytesAsBase64, bytesFromFile, rerunPrevious, addRepeatedManually bool) error {
+	return dm.CallRPCInteractively(ctx, w, rpcName, digManually, bytesAsBase64, bytesFromFile, rerunPrevious, addRepeatedManually)
 }
 
-func (m *dependencyManager) CallRPCInteractively(ctx context.Context, w io.Writer, rpcName string, digManually, bytesFromFile, rerunPrevious, addRepeatedManually bool) error {
+func (m *dependencyManager) CallRPCInteractively(ctx context.Context, w io.Writer, rpcName string, digManually, bytesAsBase64, bytesFromFile, rerunPrevious, addRepeatedManually bool) error {
 	return m.CallRPC(ctx, w, rpcName, rerunPrevious, &interactiveFiller{
 		fillFunc: func(v interface{}) error {
 			return m.interactiveFiller.Fill(v, fill.InteractiveFillerOpts{
 				DigManually:         digManually,
+				BytesAsBase64:       bytesAsBase64,
 				BytesFromFile:       bytesFromFile,
 				AddRepeatedManually: addRepeatedManually,
 			})
-- 
2.38.1