aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Alexander <neilalexander@users.noreply.github.com>2020-10-06 14:51:32 +0100
committerGitHub <noreply@github.com>2020-10-06 14:51:32 +0100
commitd69eba10e5fb4cbe847776f1fbc6b96cbced3d66 (patch)
treee0fc8a0ed510de271fb2f5a0dfb8723f00399923
parent1eaf7aa27e5e4592cd5f8d8c3d9c42cece798748 (diff)
Add furl (#1482)
* Add furl * Add POST support
-rw-r--r--cmd/furl/main.go123
1 files changed, 123 insertions, 0 deletions
diff --git a/cmd/furl/main.go b/cmd/furl/main.go
new file mode 100644
index 00000000..efaaa4b8
--- /dev/null
+++ b/cmd/furl/main.go
@@ -0,0 +1,123 @@
+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)")
+
+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))
+}