File: request.go

package info (click to toggle)
golang-github-scaleway-scaleway-sdk-go 1.0.0~beta12-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,000 kB
  • sloc: javascript: 160; sh: 70; makefile: 3
file content (122 lines) | stat: -rw-r--r-- 2,697 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package scw

import (
	"bytes"
	"context"
	"encoding/json"
	"io"
	"net/http"
	"net/url"

	"github.com/scaleway/scaleway-sdk-go/internal/auth"
	"github.com/scaleway/scaleway-sdk-go/internal/errors"
)

// ScalewayRequest contains all the contents related to performing a request on the Scaleway API.
type ScalewayRequest struct {
	Method  string
	Path    string
	Headers http.Header
	Query   url.Values
	Body    io.Reader

	// request options
	ctx      context.Context
	auth     auth.Auth
	allPages bool
	zones    []Zone
	regions  []Region
}

// getAllHeaders constructs a http.Header object and aggregates all headers into the object.
func (req *ScalewayRequest) getAllHeaders(token auth.Auth, userAgent string, anonymized bool) http.Header {
	var allHeaders http.Header
	if anonymized {
		allHeaders = token.AnonymizedHeaders()
	} else {
		allHeaders = token.Headers()
	}

	allHeaders.Set("User-Agent", userAgent)
	if req.Body != nil {
		allHeaders.Set("Content-Type", "application/json")
	}
	for key, value := range req.Headers {
		allHeaders.Del(key)
		for _, v := range value {
			allHeaders.Add(key, v)
		}
	}

	return allHeaders
}

// getURL constructs a URL based on the base url and the client.
func (req *ScalewayRequest) getURL(baseURL string) (*url.URL, error) {
	url, err := url.Parse(baseURL + req.Path)
	if err != nil {
		return nil, errors.New("invalid url %s: %s", baseURL+req.Path, err)
	}
	url.RawQuery = req.Query.Encode()

	return url, nil
}

// SetBody json marshal the given body and write the json content type
// to the request. It also catches when body is a file.
func (req *ScalewayRequest) SetBody(body interface{}) error {
	var contentType string
	var content io.Reader

	switch b := body.(type) {
	case *File:
		contentType = b.ContentType
		content = b.Content
	case io.Reader:
		contentType = "text/plain"
		content = b
	default:
		buf, err := json.Marshal(body)
		if err != nil {
			return err
		}
		contentType = "application/json"
		content = bytes.NewReader(buf)
	}

	if req.Headers == nil {
		req.Headers = http.Header{}
	}

	req.Headers.Set("Content-Type", contentType)
	req.Body = content

	return nil
}

func (req *ScalewayRequest) apply(opts []RequestOption) {
	for _, opt := range opts {
		opt(req)
	}
}

func (req *ScalewayRequest) validate() error {
	// nothing so far
	return nil
}

func (req *ScalewayRequest) clone() *ScalewayRequest {
	clonedReq := &ScalewayRequest{
		Method:   req.Method,
		Path:     req.Path,
		Headers:  req.Headers.Clone(),
		ctx:      req.ctx,
		auth:     req.auth,
		allPages: req.allPages,
		zones:    req.zones,
	}
	if req.Query != nil {
		clonedReq.Query = url.Values(http.Header(req.Query).Clone())
	}
	return clonedReq
}