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"
|
2013-11-19 01:09:56 +01:00
|
|
|
_ "crypto/sha512"
|
|
|
|
"crypto/tls"
|
|
|
|
"crypto/x509"
|
2013-05-10 22:16:18 +02:00
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
2013-06-14 18:19:50 +02:00
|
|
|
"strings"
|
2013-05-10 22:16:18 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
// MarshallAndSend takes the reply structure, marshalls it to json, and
|
2013-05-14 16:13:44 +02:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
|
|
|
// jsonRpcSend connects to the daemon with the specified username, password,
|
|
|
|
// 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.
|
2013-11-19 01:09:56 +01: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"
|
|
|
|
}
|
2013-06-14 18:19:50 +02:00
|
|
|
credentials := user + ":" + password
|
2013-11-19 01:09:56 +01:00
|
|
|
resp, err := client.Post(protocol+"://"+credentials+"@"+server,
|
2013-05-10 22:16:18 +02:00
|
|
|
"application/json", bytes.NewBuffer(message))
|
2013-06-14 17:47:09 +02:00
|
|
|
if err != nil {
|
|
|
|
// We do not want to log the username/password in the errors.
|
2013-06-14 18:19:50 +02:00
|
|
|
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)
|
|
|
|
return body, err
|
|
|
|
}
|
|
|
|
return body, nil
|
|
|
|
}
|