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 }