1package main 2 3import ( 4 "bufio" 5 "bytes" 6 "context" 7 "crypto/ed25519" 8 "encoding/json" 9 "encoding/pem" 10 "flag" 11 "fmt" 12 "io/ioutil" 13 "net/url" 14 "os" 15 16 "github.com/matrix-org/gomatrixserverlib" 17) 18 19var requestFrom = flag.String("from", "", "the server name that the request should originate from") 20var requestKey = flag.String("key", "matrix_key.pem", "the private key to use when signing the request") 21var requestPost = flag.Bool("post", false, "send a POST request instead of GET (pipe input into stdin or type followed by Ctrl-D)") 22 23func main() { 24 flag.Parse() 25 26 if requestFrom == nil || *requestFrom == "" { 27 fmt.Println("expecting: furl -from origin.com [-key matrix_key.pem] https://path/to/url") 28 fmt.Println("supported flags:") 29 flag.PrintDefaults() 30 os.Exit(1) 31 } 32 33 data, err := ioutil.ReadFile(*requestKey) 34 if err != nil { 35 panic(err) 36 } 37 38 var privateKey ed25519.PrivateKey 39 keyBlock, _ := pem.Decode(data) 40 if keyBlock == nil { 41 panic("keyBlock is nil") 42 } 43 if keyBlock.Type == "MATRIX PRIVATE KEY" { 44 _, privateKey, err = ed25519.GenerateKey(bytes.NewReader(keyBlock.Bytes)) 45 if err != nil { 46 panic(err) 47 } 48 } else { 49 panic("unexpected key block") 50 } 51 52 client := gomatrixserverlib.NewFederationClient( 53 gomatrixserverlib.ServerName(*requestFrom), 54 gomatrixserverlib.KeyID(keyBlock.Headers["Key-ID"]), 55 privateKey, 56 ) 57 58 u, err := url.Parse(flag.Arg(0)) 59 if err != nil { 60 panic(err) 61 } 62 63 var bodyObj interface{} 64 var bodyBytes []byte 65 method := "GET" 66 if *requestPost { 67 method = "POST" 68 fmt.Println("Waiting for JSON input. Press Enter followed by Ctrl-D when done...") 69 70 scan := bufio.NewScanner(os.Stdin) 71 for scan.Scan() { 72 bytes := scan.Bytes() 73 bodyBytes = append(bodyBytes, bytes...) 74 } 75 fmt.Println("Done!") 76 if err = json.Unmarshal(bodyBytes, &bodyObj); err != nil { 77 panic(err) 78 } 79 } 80 81 req := gomatrixserverlib.NewFederationRequest( 82 method, 83 gomatrixserverlib.ServerName(u.Host), 84 u.RequestURI(), 85 ) 86 87 if *requestPost { 88 if err = req.SetContent(bodyObj); err != nil { 89 panic(err) 90 } 91 } 92 93 if err = req.Sign( 94 gomatrixserverlib.ServerName(*requestFrom), 95 gomatrixserverlib.KeyID(keyBlock.Headers["Key-ID"]), 96 privateKey, 97 ); err != nil { 98 panic(err) 99 } 100 101 httpReq, err := req.HTTPRequest() 102 if err != nil { 103 panic(err) 104 } 105 106 var res interface{} 107 err = client.DoRequestAndParseResponse( 108 context.TODO(), 109 httpReq, 110 &res, 111 ) 112 if err != nil { 113 panic(err) 114 } 115 116 j, err := json.MarshalIndent(res, "", " ") 117 if err != nil { 118 panic(err) 119 } 120 121 fmt.Println(string(j)) 122} 123