forked from a8m/documentdb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
request.go
92 lines (77 loc) · 2.06 KB
/
request.go
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
package documentdb
import (
"fmt"
"strings"
"time"
"net/http"
"net/url"
)
const (
HEADER_XDATE = "X-Ms-Date"
HEADER_AUTH = "Authorization"
HEADER_VER = "X-Ms-Version"
HEADER_CONTYPE = "Content-Type"
HEADER_CONLEN = "Content-Length"
HEADER_IS_QUERY = "X-Ms-Documentdb-Isquery"
)
// Request Error
type RequestError struct {
Code string `json:"code"`
Message string `json:"message"`
}
// Implement Error function
func (e RequestError) Error() string {
return fmt.Sprintf("%v, %v", e.Code, e.Message)
}
// Resource Request
type Request struct {
rId, rType string
*http.Request
}
// Return new resource request with type and id
func ResourceRequest(link string, req *http.Request) *Request {
rId, rType := parse(link)
return &Request{rId, rType, req}
}
// Add 3 default headers to *Request
// "x-ms-date", "x-ms-version", "authorization"
func (req *Request) DefaultHeaders(mKey string) (err error) {
req.Header.Add(HEADER_XDATE, time.Now().UTC().Format("Mon, 02 Jan 2006 15:04:05 GMT"))
req.Header.Add(HEADER_VER, "2017-02-22")
// Auth
parts := []string{req.Method, req.rType, req.rId, req.Header.Get(HEADER_XDATE), req.Header.Get("Date"), ""}
sign, err := authorize(strings.ToLower(strings.Join(parts, "\n")), mKey)
if err != nil {
return err
}
masterToken := "master"
tokenVersion := "1.0"
req.Header.Add(HEADER_AUTH, url.QueryEscape("type=" + masterToken + "&ver=" + tokenVersion + "&sig=" +sign))
return
}
// Add headers for query request
func (req *Request) QueryHeaders(len int) {
req.Header.Add(HEADER_CONTYPE, "application/query+json")
req.Header.Add(HEADER_IS_QUERY, "true")
req.Header.Add(HEADER_CONLEN, string(len))
}
// Get path and return resource Id and Type
// (e.g: "/dbs/b5NCAA==/" ==> "b5NCAA==", "dbs")
func parse(id string) (rId, rType string) {
if strings.HasPrefix(id, "/") == false {
id = "/" + id
}
if strings.HasSuffix(id, "/") == false {
id = id + "/"
}
parts := strings.Split(id, "/")
l := len(parts)
if l % 2 == 0 {
rId = parts[l - 2]
rType = parts[l - 3]
} else {
rId = parts[l - 3]
rType = parts[l - 2]
}
return
}