]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - shared/extra-utils/requests/requests.ts
Fix infohash with object storage
[github/Chocobozzz/PeerTube.git] / shared / extra-utils / requests / requests.ts
CommitLineData
c0e8b12e 1/* eslint-disable @typescript-eslint/no-floating-promises */
a1587156 2
9107d791 3import { decode } from 'querystring'
41fb13c3 4import request from 'supertest'
2d1ad5b9 5import { URL } from 'url'
c0e8b12e
C
6import { HttpStatusCode } from '@shared/models'
7import { buildAbsoluteFixturePath } from '../miscs/tests'
09209296 8
c0e8b12e 9export type CommonRequestParams = {
a1587156
C
10 url: string
11 path?: string
a1587156 12 contentType?: string
4c280004 13 range?: string
9107d791 14 redirects?: number
012580d9 15 accept?: string
41d1d075 16 host?: string
c0e8b12e
C
17 token?: string
18 headers?: { [ name: string ]: string }
19 type?: string
20 xForwardedFor?: string
21 expectedStatus?: HttpStatusCode
22}
eec63bbc 23
c0e8b12e
C
24function makeRawRequest (url: string, expectedStatus?: HttpStatusCode, range?: string) {
25 const { host, protocol, pathname } = new URL(url)
eec63bbc 26
c0e8b12e 27 return makeGetRequest({ url: `${protocol}//${host}`, path: pathname, expectedStatus, range })
eec63bbc
C
28}
29
c0e8b12e
C
30function makeGetRequest (options: CommonRequestParams & {
31 query?: any
fb72d2e1 32 rawQuery?: string
eec63bbc 33}) {
c0e8b12e 34 const req = request(options.url).get(options.path)
fb72d2e1
C
35
36 if (options.query) req.query(options.query)
37 if (options.rawQuery) req.query(options.rawQuery)
eec63bbc 38
c0e8b12e
C
39 return buildRequest(req, { contentType: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options })
40}
eec63bbc 41
c0e8b12e
C
42function makeHTMLRequest (url: string, path: string) {
43 return makeGetRequest({
44 url,
45 path,
46 accept: 'text/html',
47 expectedStatus: HttpStatusCode.OK_200
48 })
49}
eec63bbc 50
c0e8b12e
C
51function makeActivityPubGetRequest (url: string, path: string, expectedStatus = HttpStatusCode.OK_200) {
52 return makeGetRequest({
53 url,
54 path,
55 expectedStatus: expectedStatus,
56 accept: 'application/activity+json,text/html;q=0.9,\\*/\\*;q=0.8'
57 })
0e1dc3e7
C
58}
59
c0e8b12e
C
60function makeDeleteRequest (options: CommonRequestParams) {
61 const req = request(options.url).delete(options.path)
62
63 return buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options })
64}
65
66function makeUploadRequest (options: CommonRequestParams & {
a1587156 67 method?: 'POST' | 'PUT'
d23dd9fb 68
a1587156 69 fields: { [ fieldName: string ]: any }
77e9f859 70 attaches?: { [ attachName: string ]: any | any[] }
0e1dc3e7 71}) {
c0e8b12e
C
72 let req = options.method === 'PUT'
73 ? request(options.url).put(options.path)
74 : request(options.url).post(options.path)
0e1dc3e7 75
c0e8b12e 76 req = buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options })
ac81d1a0 77
c0e8b12e 78 buildFields(req, options.fields)
0e1dc3e7 79
77e9f859 80 Object.keys(options.attaches || {}).forEach(attach => {
0e1dc3e7 81 const value = options.attaches[attach]
c0e8b12e 82
2769e297
C
83 if (Array.isArray(value)) {
84 req.attach(attach, buildAbsoluteFixturePath(value[0]), value[1])
85 } else {
86 req.attach(attach, buildAbsoluteFixturePath(value))
87 }
0e1dc3e7
C
88 })
89
d23dd9fb 90 return req
0e1dc3e7
C
91}
92
c0e8b12e 93function makePostBodyRequest (options: CommonRequestParams & {
a1587156 94 fields?: { [ fieldName: string ]: any }
0e1dc3e7 95}) {
c0e8b12e
C
96 const req = request(options.url).post(options.path)
97 .send(options.fields)
0e1dc3e7 98
c0e8b12e 99 return buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options })
0e1dc3e7
C
100}
101
102function makePutBodyRequest (options: {
a1587156
C
103 url: string
104 path: string
105 token?: string
106 fields: { [ fieldName: string ]: any }
c0e8b12e 107 expectedStatus?: HttpStatusCode
4bbfc6c6 108}) {
c0e8b12e
C
109 const req = request(options.url).put(options.path)
110 .send(options.fields)
4bbfc6c6 111
c0e8b12e 112 return buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options })
4bbfc6c6
C
113}
114
9107d791
C
115function decodeQueryString (path: string) {
116 return decode(path.split('?')[1])
117}
118
c1bc8ee4 119function unwrapBody <T> (test: request.Test): Promise<T> {
e8bd7ce7
C
120 return test.then(res => res.body)
121}
122
c1bc8ee4
C
123function unwrapText (test: request.Test): Promise<string> {
124 return test.then(res => res.text)
125}
126
0305db28
JB
127function unwrapBodyOrDecodeToJSON <T> (test: request.Test): Promise<T> {
128 return test.then(res => {
129 if (res.body instanceof Buffer) {
130 return JSON.parse(new TextDecoder().decode(res.body))
131 }
132
133 return res.body
134 })
135}
136
137function unwrapTextOrDecode (test: request.Test): Promise<string> {
138 return test.then(res => res.text || new TextDecoder().decode(res.body))
139}
140
0e1dc3e7
C
141// ---------------------------------------------------------------------------
142
143export {
e032aec9 144 makeHTMLRequest,
0e1dc3e7 145 makeGetRequest,
9107d791 146 decodeQueryString,
ac81d1a0 147 makeUploadRequest,
0e1dc3e7 148 makePostBodyRequest,
eec63bbc 149 makePutBodyRequest,
4bbfc6c6 150 makeDeleteRequest,
09209296 151 makeRawRequest,
2d1ad5b9 152 makeActivityPubGetRequest,
c1bc8ee4 153 unwrapBody,
0305db28
JB
154 unwrapTextOrDecode,
155 unwrapBodyOrDecodeToJSON,
c0e8b12e
C
156 unwrapText
157}
158
159// ---------------------------------------------------------------------------
160
161function buildRequest (req: request.Test, options: CommonRequestParams) {
162 if (options.contentType) req.set('Accept', options.contentType)
163 if (options.token) req.set('Authorization', 'Bearer ' + options.token)
164 if (options.range) req.set('Range', options.range)
165 if (options.accept) req.set('Accept', options.accept)
166 if (options.host) req.set('Host', options.host)
167 if (options.redirects) req.redirects(options.redirects)
168 if (options.expectedStatus) req.expect(options.expectedStatus)
169 if (options.xForwardedFor) req.set('X-Forwarded-For', options.xForwardedFor)
170 if (options.type) req.type(options.type)
171
172 Object.keys(options.headers || {}).forEach(name => {
173 req.set(name, options.headers[name])
174 })
175
176 return req
177}
178
179function buildFields (req: request.Test, fields: { [ fieldName: string ]: any }, namespace?: string) {
180 if (!fields) return
181
182 let formKey: string
183
184 for (const key of Object.keys(fields)) {
185 if (namespace) formKey = `${namespace}[${key}]`
186 else formKey = key
187
188 if (fields[key] === undefined) continue
189
190 if (Array.isArray(fields[key]) && fields[key].length === 0) {
63436fc5 191 req.field(key, [])
c0e8b12e
C
192 continue
193 }
194
195 if (fields[key] !== null && typeof fields[key] === 'object') {
196 buildFields(req, fields[key], formKey)
197 } else {
198 req.field(formKey, fields[key])
199 }
200 }
0e1dc3e7 201}