2018-05-17 17:26:18 +03:00
|
|
|
package v1
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
2018-12-05 17:14:51 +03:00
|
|
|
"io"
|
2018-05-17 17:26:18 +03:00
|
|
|
"net/http"
|
2019-08-14 14:18:12 +03:00
|
|
|
"strings"
|
2018-05-17 17:26:18 +03:00
|
|
|
)
|
|
|
|
|
2024-02-12 14:31:57 +03:00
|
|
|
const MaxRPS = 100
|
|
|
|
|
2018-07-21 18:56:25 +03:00
|
|
|
var prefix = "/api/transport/v1"
|
2018-05-17 17:26:18 +03:00
|
|
|
|
2023-12-28 14:26:49 +03:00
|
|
|
// GetRequest performs GET request to the provided route.
|
2018-10-03 09:48:07 +03:00
|
|
|
func (c *MgClient) GetRequest(url string, parameters []byte) ([]byte, int, error) {
|
|
|
|
return makeRequest(
|
|
|
|
"GET",
|
|
|
|
fmt.Sprintf("%s%s%s", c.URL, prefix, url),
|
|
|
|
bytes.NewBuffer(parameters),
|
|
|
|
c,
|
|
|
|
)
|
2018-05-17 17:26:18 +03:00
|
|
|
}
|
|
|
|
|
2023-12-28 14:26:49 +03:00
|
|
|
// PostRequest performs POST request to the provided route.
|
2018-12-05 17:14:51 +03:00
|
|
|
func (c *MgClient) PostRequest(url string, parameters io.Reader) ([]byte, int, error) {
|
2018-05-17 17:26:18 +03:00
|
|
|
return makeRequest(
|
|
|
|
"POST",
|
|
|
|
fmt.Sprintf("%s%s%s", c.URL, prefix, url),
|
2018-12-05 17:14:51 +03:00
|
|
|
parameters,
|
2018-05-17 17:26:18 +03:00
|
|
|
c,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2023-12-28 14:26:49 +03:00
|
|
|
// PutRequest performs PUT request to the provided route.
|
2018-05-17 17:26:18 +03:00
|
|
|
func (c *MgClient) PutRequest(url string, parameters []byte) ([]byte, int, error) {
|
|
|
|
return makeRequest(
|
|
|
|
"PUT",
|
|
|
|
fmt.Sprintf("%s%s%s", c.URL, prefix, url),
|
|
|
|
bytes.NewBuffer(parameters),
|
|
|
|
c,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2023-12-28 14:26:49 +03:00
|
|
|
// DeleteRequest performs DELETE request to the provided route.
|
2018-05-21 17:56:42 +03:00
|
|
|
func (c *MgClient) DeleteRequest(url string, parameters []byte) ([]byte, int, error) {
|
2018-05-17 17:26:18 +03:00
|
|
|
return makeRequest(
|
|
|
|
"DELETE",
|
|
|
|
fmt.Sprintf("%s%s%s", c.URL, prefix, url),
|
2018-05-21 17:56:42 +03:00
|
|
|
bytes.NewBuffer(parameters),
|
2018-05-17 17:26:18 +03:00
|
|
|
c,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2024-02-15 21:59:10 +03:00
|
|
|
func (c *MgClient) WaitForRateLimit() {
|
|
|
|
if c.limiter != nil && c.Token != "" {
|
|
|
|
c.limiter.Obtain(c.Token)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-05 17:14:51 +03:00
|
|
|
func makeRequest(reqType, url string, buf io.Reader, c *MgClient) ([]byte, int, error) {
|
2018-05-17 17:26:18 +03:00
|
|
|
var res []byte
|
|
|
|
req, err := http.NewRequest(reqType, url, buf)
|
|
|
|
if err != nil {
|
|
|
|
return res, 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
req.Header.Set("X-Transport-Token", c.Token)
|
|
|
|
|
2024-02-16 09:28:35 +03:00
|
|
|
maxAttempt := 1
|
|
|
|
if c.limiter != nil && c.Token != "" {
|
|
|
|
maxAttempt = 3
|
|
|
|
}
|
|
|
|
|
2024-02-12 14:31:57 +03:00
|
|
|
attempt := 0
|
|
|
|
tryAgain:
|
2024-02-15 21:59:10 +03:00
|
|
|
c.WaitForRateLimit()
|
2024-02-13 12:13:49 +03:00
|
|
|
if c.Debug {
|
|
|
|
if strings.Contains(url, "/files/upload") {
|
|
|
|
c.writeLog("MG TRANSPORT API Request: %s %s %s [file data]", reqType, url, c.Token)
|
|
|
|
} else {
|
|
|
|
c.writeLog("MG TRANSPORT API Request: %s %s %s %v", reqType, url, c.Token, buf)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-17 17:26:18 +03:00
|
|
|
resp, err := c.httpClient.Do(req)
|
|
|
|
if err != nil {
|
2022-10-25 17:32:46 +03:00
|
|
|
return res, 0, NewCriticalHTTPError(err)
|
2018-05-17 17:26:18 +03:00
|
|
|
}
|
|
|
|
|
2024-02-16 09:28:35 +03:00
|
|
|
if resp.StatusCode == http.StatusTooManyRequests && attempt < maxAttempt {
|
2024-02-12 14:31:57 +03:00
|
|
|
attempt++
|
2024-02-13 12:13:49 +03:00
|
|
|
c.writeLog("MG TRANSPORT API Request rate limit hit on attempt %d, retrying", attempt)
|
2024-02-12 14:31:57 +03:00
|
|
|
goto tryAgain
|
|
|
|
}
|
|
|
|
|
2022-10-26 10:54:54 +03:00
|
|
|
if resp.StatusCode >= http.StatusInternalServerError {
|
|
|
|
err = NewServerError(resp)
|
|
|
|
return res, resp.StatusCode, err
|
|
|
|
}
|
|
|
|
|
2022-10-26 14:58:32 +03:00
|
|
|
res, err = buildLimitedRawResponse(resp)
|
2018-05-17 17:26:18 +03:00
|
|
|
if err != nil {
|
|
|
|
return res, 0, err
|
|
|
|
}
|
|
|
|
|
2018-06-20 15:27:46 +03:00
|
|
|
if c.Debug {
|
2021-11-22 16:16:01 +03:00
|
|
|
c.writeLog("MG TRANSPORT API Response: %s", res)
|
2018-06-20 15:27:46 +03:00
|
|
|
}
|
|
|
|
|
2018-05-17 17:26:18 +03:00
|
|
|
return res, resp.StatusCode, err
|
|
|
|
}
|