-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathcurl.go
131 lines (116 loc) · 2.93 KB
/
curl.go
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
package main
import (
"context"
"encoding/base64"
"fmt"
"os"
"os/exec"
"strings"
"github.com/urfave/cli/v3"
"github.com/nbd-wtf/go-nostr"
"golang.org/x/exp/slices"
)
var curlFlags []string
var curl = &cli.Command{
Name: "curl",
Usage: "calls curl but with a nip98 header",
Description: "accepts all flags and arguments exactly as they would be passed to curl.",
Flags: defaultKeyFlags,
Action: func(ctx context.Context, c *cli.Command) error {
kr, _, err := gatherKeyerFromArguments(ctx, c)
if err != nil {
return err
}
// cowboy parsing of curl flags to get the data we need for nip98
var url string
var method string
var presumedMethod string
curlBodyBuildingFlags := []string{
"-d",
"--data",
"--data-binary",
"--data-ascii",
"--data-raw",
"--data-urlencode",
"-F",
"--form",
"--form-string",
"--form-escape",
"--upload-file",
}
nextIsMethod := false
for _, f := range curlFlags {
if nextIsMethod {
method = f
method, _ = strings.CutPrefix(method, `"`)
method, _ = strings.CutSuffix(method, `"`)
method = strings.ToUpper(method)
} else if strings.HasPrefix(f, "https://") || strings.HasPrefix(f, "http://") {
url = f
} else if f == "--request" || f == "-X" {
nextIsMethod = true
continue
} else if slices.Contains(curlBodyBuildingFlags, f) ||
slices.ContainsFunc(curlBodyBuildingFlags, func(s string) bool {
return strings.HasPrefix(f, s)
}) {
presumedMethod = "POST"
}
nextIsMethod = false
}
if url == "" {
return fmt.Errorf("can't create nip98 event: target url is empty")
}
if method == "" {
if presumedMethod != "" {
method = presumedMethod
} else {
method = "GET"
}
}
// make and sign event
evt := nostr.Event{
Kind: 27235,
CreatedAt: nostr.Now(),
Tags: nostr.Tags{
{"u", url},
{"method", method},
},
}
if err := kr.SignEvent(ctx, &evt); err != nil {
return err
}
// the first 2 indexes of curlFlags were reserved for this
curlFlags[0] = "-H"
curlFlags[1] = fmt.Sprintf("Authorization: Nostr %s", base64.StdEncoding.EncodeToString([]byte(evt.String())))
// call curl
cmd := exec.Command("curl", curlFlags...)
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Run()
return nil
},
}
func realCurl() error {
curlFlags = make([]string, 2, max(len(os.Args)-4, 2))
keyFlags := make([]string, 0, 5)
for i := 0; i < len(os.Args[2:]); i++ {
arg := os.Args[i+2]
if slices.ContainsFunc(defaultKeyFlags, func(f cli.Flag) bool {
bareArg, _ := strings.CutPrefix(arg, "-")
bareArg, _ = strings.CutPrefix(bareArg, "-")
return slices.Contains(f.Names(), bareArg)
}) {
keyFlags = append(keyFlags, arg)
if arg != "--prompt-sec" {
i++
val := os.Args[i+2]
keyFlags = append(keyFlags, val)
}
} else {
curlFlags = append(curlFlags, arg)
}
}
return curl.Run(context.Background(), keyFlags)
}