Dernière activité 1726624354

r.go Brut
1func Fetch(
2 sfo *state.StateFetchOptions,
3 efo ExtraFetchOptions,
4 opts FetchOptions,
5) (*ClientResponse, error) {
6 for {
7 var headers = map[string]string{}
8
9 if !efo.NoExtraHeaders {
10 headers["Content-Type"] = "application/json"
11 }
12
13 if len(efo.Headers) > 0 {
14 for k, v := range efo.Headers {
15 headers[k] = v
16 }
17 }
18
19 if efo.Session != nil {
20 sess, err := efo.Session.GetCurrentSession()
21
22 if err != nil {
23 return nil, err
24 }
25
26 headers["Authorization"] = fmt.Sprintf("Bearer %v", *sess.Token)
27 }
28
29 req, err := http.NewRequest(opts.Method, opts.URL, opts.Body)
30
31 if err != nil {
32 return nil, err
33 }
34
35 for k, v := range headers {
36 req.Header.Set(k, v)
37 }
38
39 resp, err := FetchHttpClient.Do(req)
40
41 if err != nil {
42 return nil, err
43 }
44
45 if slices.Contains([]int{408, 502, 503, 504}, resp.StatusCode) {
46 return nil, ErrServerMaintenance
47 }
48
49 retryAfterStr := resp.Header.Get("Retry-After")
50
51 if retryAfterStr != "" {
52 // NOTE: We use milliseconds here even though the API *currently* returns seconds
53 // to make it easier to change in the future
54 retryAfter, err := strconv.ParseFloat(retryAfterStr, 64)
55
56 if err != nil {
57 retryAfter = 3000
58 } else {
59 retryAfter *= 1000
60 }
61
62 if efo.OnRatelimit != nil {
63 efo.OnRatelimit(opts, retryAfter, err, sfo, efo.Session)
64 }
65
66 // Wait for the time specified by the server
67 if !efo.NoWait {
68 time.Sleep(time.Duration(retryAfter) * time.Second)
69
70 if _, err := opts.Body.Seek(0, io.SeekStart); err != nil {
71 return nil, err
72 }
73
74 if efo.OnRatelimit != nil {
75 efo.OnRatelimit(opts, 0, err, sfo, efo.Session)
76 }
77
78 continue
79 }
80 }
81
82 return NewClientResponse(resp), nil
83 }
84}
85