github.com/clocklock/go-rfc3161@v0.0.0-20160419203229-5ea544d9dee0/client.go (about)

     1  package rfc3161
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/asn1"
     6  	"errors"
     7  	"io/ioutil"
     8  	"net/http"
     9  )
    10  
    11  // Errors
    12  var (
    13  	ErrRequestFailed = errors.New("rfc3161: client: Request failed")
    14  )
    15  
    16  // Client handles requests to an HTTP or websocket time-stamp-service
    17  // You may override the underlying http client used by setting the HTTPClient field
    18  type Client struct {
    19  	HTTPClient *http.Client
    20  	URL        string
    21  }
    22  
    23  // NewClient creates a new rfc3161.Client given a URL.
    24  func NewClient(url string) *Client {
    25  	client := new(Client)
    26  	client.HTTPClient = http.DefaultClient
    27  	client.URL = url
    28  	return client
    29  }
    30  
    31  // Do a time stamp request and get back the Time Stamp Response.
    32  // This will not verify the response. It is the caller's responsibility
    33  // to call resp.Verify() on the returned TimeStampResp.
    34  func (client *Client) Do(tsq *TimeStampReq) (*TimeStampResp, error) {
    35  	der, err := asn1.Marshal(tsq)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  
    40  	req, err := http.NewRequest("POST", client.URL, bytes.NewBuffer(der))
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  	req.Header.Set("Content-Type", "application/timestamp-query")
    45  
    46  	resp, err := client.HTTPClient.Do(req)
    47  	defer resp.Body.Close()
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  
    52  	body, err := ioutil.ReadAll(resp.Body)
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  
    57  	tsr := new(TimeStampResp)
    58  	rest, err := asn1.Unmarshal(body, tsr)
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  	if len(rest) != 0 {
    63  		return nil, ErrUnrecognizedData
    64  	}
    65  
    66  	if tsr.Status.Status.IsError() {
    67  		return tsr, &tsr.Status
    68  	}
    69  	return tsr, nil
    70  }