Example #1
0
// JsonRequest JSON encodes and sends the object in reqData.ReqValue (if any) to the specified URL.
// Optional method arguments are passed using the RequestData object.
// Relevant RequestData fields:
// ReqHeaders: additional HTTP header values to add to the request.
// ExpectedStatus: the allowed HTTP response status values, else an error is returned.
// ReqValue: the data object to send.
// RespValue: the data object to decode the result into.
func (c *Client) JsonRequest(method, url string, reqData *RequestData) (err error) {
	err = nil
	var body []byte
	if reqData.Params != nil {
		url += "?" + reqData.Params.Encode()
	}
	if sbody, ok := reqData.ReqValue.(string); ok {
		body = []byte(sbody)
	} else if reqData.ReqValue != nil {
		body, err = json.Marshal(reqData.ReqValue)
		if err != nil {
			err = errors.Newf(err, "failed marshalling the request body")
			return
		}
	}
	headers := c.createHeaders(reqData.ReqHeaders, contentTypeJSON)
	respBody, statusCode, err := c.sendRequest(
		method, url, bytes.NewReader(body), len(body), headers, reqData.ExpectedStatus)
	reqData.StatusCode = statusCode
	log.Tracef("%s:%s", method, url)

	if err != nil {
		return
	}
	err = unmarshallResponse(respBody, reqData)
	return
}
Example #2
0
func unmarshallResponse(respBody io.ReadCloser, reqData *RequestData) (err error) {
	defer respBody.Close()
	respData, err := ioutil.ReadAll(respBody)
	if err != nil {
		err = errors.Newf(err, "failed reading the response body")
		return
	}
	if len(respData) > 0 {
		if reqData.RespValue != nil {
			err = json.Unmarshal(respData, &reqData.RespValue)
			if err != nil {
				err = errors.Newf(err, "failed unmarshaling the response body: %s", respData)
			}
		}
	}
	return
}
Example #3
0
func (c *Client) sendRateLimitedRequest(method, URL string, headers http.Header, reqReader io.Reader, /*reqData []byte,*/
) (resp *http.Response, err error) {
	for i := 0; i < c.maxSendAttempts; i++ {
		/*
		 * var reqReader io.Reader
		 * if reqData != nil {
		 *	reqReader = bytes.NewReader(reqData)
		 * }
		 */
		req, err := http.NewRequest(method, URL, reqReader)
		if err != nil {
			err = errors.Newf(err, "failed creating the request %s", URL)
			return nil, err
		}
		for header, values := range headers {
			for _, value := range values {
				req.Header.Add(header, value)
			}
		}

		resp, err = c.Do(req)
		log.Tracef("%s: %s", method, URL)
		if err != nil {
			return nil, errors.Newf(err, "failed executing the request %s", URL)
		}
		if resp.StatusCode != http.StatusRequestEntityTooLarge || resp.Header.Get("Retry-After") == "" {
			return resp, nil
		}
		resp.Body.Close()
		retryAfter, err := strconv.ParseFloat(resp.Header.Get("Retry-After"), 32)
		if err != nil {
			return nil, errors.Newf(err, "Invalid Retry-After header %s", URL)
		}
		if retryAfter == 0 {
			return nil, errors.Newf(err, "Resource limit exeeded at URL %s", URL)
		}
		log.Debugf("Too many requests, retrying in %dms.", int(retryAfter*1000))

		time.Sleep(time.Duration(retryAfter) * time.Second)
	}
	return nil, errors.Newf(err, "Maximum number of attempts (%d) reached sending request to %s", c.maxSendAttempts, URL)
}
Example #4
0
func (c *Client) PlainRequest(method, url string, reqData *RequestData) (resp []byte, err error) {
	err = nil
	var body []byte
	if reqData.Params != nil {
		url += "?" + reqData.Params.Encode()
	}
	if sbody, ok := reqData.ReqValue.(string); ok {
		body = []byte(sbody)
	} else if reqData.ReqValue != nil {
		body, err = json.Marshal(reqData.ReqValue)
		if err != nil {
			err = errors.Newf(err, "failed marshalling the request body")
			return
		}
	}
	headers := c.createHeaders(reqData.ReqHeaders, "text/plain")
	respBody, statusCode, err := c.sendRequest(method, url, bytes.NewReader(body), len(body), headers, reqData.ExpectedStatus)
	reqData.StatusCode = statusCode
	resp, err = ioutil.ReadAll(respBody)
	return
}