// Do holds a JSON-RPC request. func Do(url, method string, args *openstack.Args) error { message, err := json.EncodeClientRequest(method, args) checkErr(err) req, err := http.NewRequest("POST", url, bytes.NewBuffer(message)) checkErr(err) req.Header.Set("Content-Type", "application/json") client := new(http.Client) resp, err := client.Do(req) if err != nil { log.Printf("Error in sending request to %s. %s", url, err) return err } defer resp.Body.Close() err = json.DecodeClientResponse(resp.Body, &result) if err != nil { log.Printf("Couldn't decode response. %s", err) return err } log.Printf("url: %s, method: %s, args: %s", url, method, args) return nil }
func (rc *RpcClient) Execute(method string, req, res interface{}) error { buf, _ := json.EncodeClientRequest(method, req) body := bytes.NewBuffer(buf) log.Println(body) httpreq, _ := http.NewRequest("POST", rc.Address, body) httpreq.Header.Set("Content-Type", "application/json") response, err := rc.Httpclient.Do(httpreq) if err != nil { return err } return json.DecodeClientResponse(response.Body, res) }
// newRPCRequest initiate a new client RPC request func newRPCRequest(url string, op rpcOperation, transport http.RoundTripper) (*rpcRequest, *probe.Error) { params, err := json.EncodeClientRequest(op.Method, op.Request) if err != nil { return nil, probe.NewError(err) } req, err := http.NewRequest("POST", url, bytes.NewReader(params)) if err != nil { return nil, probe.NewError(err) } rpcReq := &rpcRequest{} rpcReq.req = req rpcReq.req.Header.Set("Content-Type", "application/json") if transport == nil { transport = http.DefaultTransport } rpcReq.transport = transport return rpcReq, nil }
// newRPCRequest initiate a new client RPC request func newRPCRequest(config *AuthConfig, url string, op rpcOperation, transport http.RoundTripper) (*rpcRequest, *probe.Error) { t := time.Now().UTC() params, err := json.EncodeClientRequest(op.Method, op.Request) if err != nil { return nil, probe.NewError(err) } body := bytes.NewReader(params) req, err := http.NewRequest("POST", url, body) if err != nil { return nil, probe.NewError(err) } req.Header.Set("x-minio-date", t.Format(iso8601Format)) // save for subsequent use hash := func() string { sum256Bytes, _ := sum256Reader(body) return hex.EncodeToString(sum256Bytes) } hashedPayload := hash() req.Header.Set("Content-Type", "application/json") req.Header.Set("x-minio-content-sha256", hashedPayload) var headers []string vals := make(map[string][]string) for k, vv := range req.Header { if _, ok := ignoredHeaders[http.CanonicalHeaderKey(k)]; ok { continue // ignored header } headers = append(headers, strings.ToLower(k)) vals[strings.ToLower(k)] = vv } headers = append(headers, "host") sort.Strings(headers) var canonicalHeaders bytes.Buffer for _, k := range headers { canonicalHeaders.WriteString(k) canonicalHeaders.WriteByte(':') switch { case k == "host": canonicalHeaders.WriteString(req.URL.Host) fallthrough default: for idx, v := range vals[k] { if idx > 0 { canonicalHeaders.WriteByte(',') } canonicalHeaders.WriteString(v) } canonicalHeaders.WriteByte('\n') } } signedHeaders := strings.Join(headers, ";") req.URL.RawQuery = strings.Replace(req.URL.Query().Encode(), "+", "%20", -1) encodedPath := getURLEncodedName(req.URL.Path) // convert any space strings back to "+" encodedPath = strings.Replace(encodedPath, "+", "%20", -1) // // canonicalRequest = // <HTTPMethod>\n // <CanonicalURI>\n // <CanonicalQueryString>\n // <CanonicalHeaders>\n // <SignedHeaders>\n // <HashedPayload> // canonicalRequest := strings.Join([]string{ req.Method, encodedPath, req.URL.RawQuery, canonicalHeaders.String(), signedHeaders, hashedPayload, }, "\n") scope := strings.Join([]string{ t.Format(yyyymmdd), "us-east-1", "rpc", "rpc_request", }, "/") stringToSign := rpcAuthHeaderPrefix + "\n" + t.Format(iso8601Format) + "\n" stringToSign = stringToSign + scope + "\n" stringToSign = stringToSign + hex.EncodeToString(sum256([]byte(canonicalRequest))) date := sumHMAC([]byte("MINIO"+config.Users["admin"].SecretAccessKey), []byte(t.Format(yyyymmdd))) region := sumHMAC(date, []byte("us-east-1")) service := sumHMAC(region, []byte("rpc")) signingKey := sumHMAC(service, []byte("rpc_request")) signature := hex.EncodeToString(sumHMAC(signingKey, []byte(stringToSign))) // final Authorization header parts := []string{ rpcAuthHeaderPrefix + " Credential=admin/" + scope, "SignedHeaders=" + signedHeaders, "Signature=" + signature, } auth := strings.Join(parts, ", ") req.Header.Set("Authorization", auth) rpcReq := &rpcRequest{} rpcReq.req = req if transport == nil { transport = http.DefaultTransport } rpcReq.transport = transport return rpcReq, nil }