lbcd/btcjson/jsonfxns.go

80 lines
2.4 KiB
Go
Raw Normal View History

2014-01-09 06:49:06 +01:00
// Copyright (c) 2013-2014 Conformal Systems LLC.
2013-05-10 22:16:18 +02:00
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcjson
import (
"bytes"
2014-09-05 19:44:04 +02:00
// Need to import this size it registers hash we need.
_ "crypto/sha512"
"crypto/tls"
"crypto/x509"
2013-05-10 22:16:18 +02:00
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"strings"
2013-05-10 22:16:18 +02:00
)
// MarshallAndSend takes the reply structure, marshalls it to json, and
// sends it back to the io.Writer (most likely an http.ResponseWriter).
// returning a log message and an error if there is one.
func MarshallAndSend(rawReply Reply, w io.Writer) (string, error) {
2013-05-10 22:16:18 +02:00
finalReply, err := json.Marshal(rawReply)
if err != nil {
msg := fmt.Sprintf("[RPCS] Error Marshalling reply: %v", err)
return msg, err
}
fmt.Fprintf(w, "%s\n", finalReply)
msg := fmt.Sprintf("[RPCS] reply: %v", rawReply)
return msg, nil
}
2014-09-05 19:44:04 +02:00
// jsonRPCSend connects to the daemon with the specified username, password,
2013-05-10 22:16:18 +02:00
// and ip/port and then send the supplied message. This uses net/http rather
// than net/rpc/jsonrpc since that one doesn't support http connections and is
// therefore useless.
2014-09-05 19:44:04 +02:00
func jsonRPCSend(user string, password string, server string, message []byte,
https bool, certificates []byte, skipverify bool) (*http.Response, error) {
client := &http.Client{}
protocol := "http"
if https {
pool := x509.NewCertPool()
pool.AppendCertsFromPEM(certificates)
config := &tls.Config{
InsecureSkipVerify: skipverify,
RootCAs: pool,
}
transport := &http.Transport{TLSClientConfig: config}
client.Transport = transport
protocol = "https"
}
credentials := url.UserPassword(user, password).String()
resp, err := client.Post(protocol+"://"+credentials+"@"+server,
2014-06-05 19:52:37 +02:00
"application/json", bytes.NewReader(message))
2013-06-14 17:47:09 +02:00
if err != nil {
// We do not want to log the username/password in the errors.
replaceStr := "<username>:<password>"
str := strings.Replace(err.Error(), credentials, replaceStr, -1)
err = fmt.Errorf("%v", str)
2013-06-14 17:47:09 +02:00
}
2013-05-10 22:16:18 +02:00
return resp, err
}
// GetRaw should be called after JsonRpcSend. It reads and returns
2013-08-15 16:15:25 +02:00
// the reply (which you can then call ReadResultCmd() on) and closes the
2013-05-10 22:16:18 +02:00
// connection.
func GetRaw(resp io.ReadCloser) ([]byte, error) {
body, err := ioutil.ReadAll(resp)
resp.Close()
if err != nil {
err = fmt.Errorf("error reading json reply: %v", err)
2013-05-10 22:16:18 +02:00
return body, err
}
return body, nil
}