aboutsummaryrefslogtreecommitdiff
path: root/cmd/furl/main.go
diff options
context:
space:
mode:
authorNeil Alexander <neilalexander@users.noreply.github.com>2020-10-07 18:39:25 +0100
committerNeil Alexander <neilalexander@users.noreply.github.com>2020-10-07 18:39:25 +0100
commit15bf3851415dc21ebcfa98e0f2a5ec725034d6dd (patch)
treecbadffd61e16681144aa93699b675b4cb07a7aa4 /cmd/furl/main.go
parente7d9eea4a09be7b05a87b1df2a9e87d3109e8fcc (diff)
parent8bca7a83a98a310e4adae405d125dda93c8db1a0 (diff)
Merge branch 'master' into v0.1.0
Diffstat (limited to 'cmd/furl/main.go')
-rw-r--r--cmd/furl/main.go124
1 files changed, 124 insertions, 0 deletions
diff --git a/cmd/furl/main.go b/cmd/furl/main.go
new file mode 100644
index 00000000..3955ef0c
--- /dev/null
+++ b/cmd/furl/main.go
@@ -0,0 +1,124 @@
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "context"
+ "crypto/ed25519"
+ "encoding/json"
+ "encoding/pem"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "net/url"
+ "os"
+
+ "github.com/matrix-org/gomatrixserverlib"
+)
+
+var requestFrom = flag.String("from", "", "the server name that the request should originate from")
+var requestKey = flag.String("key", "matrix_key.pem", "the private key to use when signing the request")
+var requestPost = flag.Bool("post", false, "send a POST request instead of GET (pipe input into stdin or type followed by Ctrl-D)")
+
+// nolint:gocyclo
+func main() {
+ flag.Parse()
+
+ if requestFrom == nil || *requestFrom == "" {
+ fmt.Println("expecting: furl -from origin.com [-key matrix_key.pem] https://path/to/url")
+ fmt.Println("supported flags:")
+ flag.PrintDefaults()
+ os.Exit(1)
+ }
+
+ data, err := ioutil.ReadFile(*requestKey)
+ if err != nil {
+ panic(err)
+ }
+
+ var privateKey ed25519.PrivateKey
+ keyBlock, _ := pem.Decode(data)
+ if keyBlock == nil {
+ panic("keyBlock is nil")
+ }
+ if keyBlock.Type == "MATRIX PRIVATE KEY" {
+ _, privateKey, err = ed25519.GenerateKey(bytes.NewReader(keyBlock.Bytes))
+ if err != nil {
+ panic(err)
+ }
+ } else {
+ panic("unexpected key block")
+ }
+
+ client := gomatrixserverlib.NewFederationClient(
+ gomatrixserverlib.ServerName(*requestFrom),
+ gomatrixserverlib.KeyID(keyBlock.Headers["Key-ID"]),
+ privateKey,
+ false,
+ )
+
+ u, err := url.Parse(flag.Arg(0))
+ if err != nil {
+ panic(err)
+ }
+
+ var bodyObj interface{}
+ var bodyBytes []byte
+ method := "GET"
+ if *requestPost {
+ method = "POST"
+ fmt.Println("Waiting for JSON input. Press Enter followed by Ctrl-D when done...")
+
+ scan := bufio.NewScanner(os.Stdin)
+ for scan.Scan() {
+ bytes := scan.Bytes()
+ bodyBytes = append(bodyBytes, bytes...)
+ }
+ fmt.Println("Done!")
+ if err = json.Unmarshal(bodyBytes, &bodyObj); err != nil {
+ panic(err)
+ }
+ }
+
+ req := gomatrixserverlib.NewFederationRequest(
+ method,
+ gomatrixserverlib.ServerName(u.Host),
+ u.RequestURI(),
+ )
+
+ if *requestPost {
+ if err = req.SetContent(bodyObj); err != nil {
+ panic(err)
+ }
+ }
+
+ if err = req.Sign(
+ gomatrixserverlib.ServerName(*requestFrom),
+ gomatrixserverlib.KeyID(keyBlock.Headers["Key-ID"]),
+ privateKey,
+ ); err != nil {
+ panic(err)
+ }
+
+ httpReq, err := req.HTTPRequest()
+ if err != nil {
+ panic(err)
+ }
+
+ var res interface{}
+ err = client.DoRequestAndParseResponse(
+ context.TODO(),
+ httpReq,
+ &res,
+ )
+ if err != nil {
+ panic(err)
+ }
+
+ j, err := json.MarshalIndent(res, "", " ")
+ if err != nil {
+ panic(err)
+ }
+
+ fmt.Println(string(j))
+}