func()

in providers/fireeye/api/client.go [62:124]


func (c *Client) Request(ctx context.Context, endpoint string) (io.Reader, error) {
	req, err := http.NewRequest("GET", c.baseURL+endpoint, nil)
	if err != nil {
		return nil, errors.Wrap(err, "cannot create http get request")
	}
	req = req.WithContext(ctx)

	acceptHeader := "application/json"
	timestamp := time.Now().Format(time.RFC1123)
	auth := c.getHash("%s%s%s%s", endpoint, acceptVersion, acceptHeader, timestamp)

	// FireEye required
	req.Header.Set("Accept", acceptHeader)
	req.Header.Set("Accept-Version", acceptVersion)
	req.Header.Set("X-Auth", c.publicKey)
	req.Header.Set("X-Auth-Hash", auth)
	req.Header.Set("Date", timestamp)

	// execute the request
	stats.IncrementCounter("request")
	resp, err := c.Do(req)
	if err != nil {
		stats.IncrementCounter("request.error")
		return nil, errors.Wrap(err, "cannot get url")
	}
	defer resp.Body.Close()

	stats.IncrementCounter(fmt.Sprintf("request.code.%d", resp.StatusCode))

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("%d - %s", resp.StatusCode, http.StatusText(resp.StatusCode))
	}

	//  response is always {success:boolean, message:something}
	// First we decode this from response, and fail fast if success = false
	// Otherwise, we return the message only

	var fireeyeResult schema.Result
	body := io.LimitReader(resp.Body, 2<<30) // 1 GB
	if err := json.NewDecoder(body).Decode(&fireeyeResult); err != nil {
		stats.IncrementCounter("request.feed.error")
		return nil, errors.Wrap(err, "couldn't decode result")
	}

	var buff bytes.Buffer
	if err := json.NewEncoder(&buff).Encode(fireeyeResult.Message); err != nil {
		stats.IncrementCounter("request.feed.error")
		return nil, errors.Wrap(err, "couldn't encode message back to buffer")
	}

	if !fireeyeResult.Success {
		stats.IncrementCounter("request.feed.error")
		var errorMessage schema.ResultErrorMessage
		if err := json.Unmarshal(buff.Bytes(), &errorMessage); err != nil {
			return nil, errors.Wrap(err, "failed to decode error message")
		}
		return nil, fmt.Errorf("%s: %s", errorMessage.Error, errorMessage.Description)
	}

	stats.IncrementCounter("request.success")

	return &buff, nil
}