]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - shared/server-commands/requests/requests.ts
Fix host advanced filter with channels
[github/Chocobozzz/PeerTube.git] / shared / server-commands / 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'
c55e3d72 6import { buildAbsoluteFixturePath } from '@shared/core-utils'
c0e8b12e 7import { HttpStatusCode } from '@shared/models'
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
790c2837
C
60function makeDeleteRequest (options: CommonRequestParams & {
61 query?: any
62 rawQuery?: string
63}) {
c0e8b12e
C
64 const req = request(options.url).delete(options.path)
65
790c2837
C
66 if (options.query) req.query(options.query)
67 if (options.rawQuery) req.query(options.rawQuery)
68
c0e8b12e
C
69 return buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options })
70}
71
72function makeUploadRequest (options: CommonRequestParams & {
a1587156 73 method?: 'POST' | 'PUT'
d23dd9fb 74
a1587156 75 fields: { [ fieldName: string ]: any }
77e9f859 76 attaches?: { [ attachName: string ]: any | any[] }
0e1dc3e7 77}) {
c0e8b12e
C
78 let req = options.method === 'PUT'
79 ? request(options.url).put(options.path)
80 : request(options.url).post(options.path)
0e1dc3e7 81
c0e8b12e 82 req = buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options })
ac81d1a0 83
c0e8b12e 84 buildFields(req, options.fields)
0e1dc3e7 85
77e9f859 86 Object.keys(options.attaches || {}).forEach(attach => {
0e1dc3e7 87 const value = options.attaches[attach]
5cf027bd 88 if (!value) return
c0e8b12e 89
2769e297
C
90 if (Array.isArray(value)) {
91 req.attach(attach, buildAbsoluteFixturePath(value[0]), value[1])
92 } else {
93 req.attach(attach, buildAbsoluteFixturePath(value))
94 }
0e1dc3e7
C
95 })
96
d23dd9fb 97 return req
0e1dc3e7
C
98}
99
c0e8b12e 100function makePostBodyRequest (options: CommonRequestParams & {
a1587156 101 fields?: { [ fieldName: string ]: any }
0e1dc3e7 102}) {
c0e8b12e
C
103 const req = request(options.url).post(options.path)
104 .send(options.fields)
0e1dc3e7 105
c0e8b12e 106 return buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options })
0e1dc3e7
C
107}
108
109function makePutBodyRequest (options: {
a1587156
C
110 url: string
111 path: string
112 token?: string
113 fields: { [ fieldName: string ]: any }
c0e8b12e 114 expectedStatus?: HttpStatusCode
4bbfc6c6 115}) {
c0e8b12e
C
116 const req = request(options.url).put(options.path)
117 .send(options.fields)
4bbfc6c6 118
c0e8b12e 119 return buildRequest(req, { accept: 'application/json', expectedStatus: HttpStatusCode.BAD_REQUEST_400, ...options })
4bbfc6c6
C
120}
121
9107d791
C
122function decodeQueryString (path: string) {
123 return decode(path.split('?')[1])
124}
125
c1bc8ee4 126function unwrapBody <T> (test: request.Test): Promise<T> {
e8bd7ce7
C
127 return test.then(res => res.body)
128}
129
c1bc8ee4
C
130function unwrapText (test: request.Test): Promise<string> {
131 return test.then(res => res.text)
132}
133
0305db28
JB
134function unwrapBodyOrDecodeToJSON <T> (test: request.Test): Promise<T> {
135 return test.then(res => {
136 if (res.body instanceof Buffer) {
137 return JSON.parse(new TextDecoder().decode(res.body))
138 }
139
140 return res.body
141 })
142}
143
144function unwrapTextOrDecode (test: request.Test): Promise<string> {
145 return test.then(res => res.text || new TextDecoder().decode(res.body))
146}
147
0e1dc3e7
C
148// ---------------------------------------------------------------------------
149
150export {
e032aec9 151 makeHTMLRequest,
0e1dc3e7 152 makeGetRequest,
9107d791 153 decodeQueryString,
ac81d1a0 154 makeUploadRequest,
0e1dc3e7 155 makePostBodyRequest,
eec63bbc 156 makePutBodyRequest,
4bbfc6c6 157 makeDeleteRequest,
09209296 158 makeRawRequest,
2d1ad5b9 159 makeActivityPubGetRequest,
c1bc8ee4 160 unwrapBody,
0305db28
JB
161 unwrapTextOrDecode,
162 unwrapBodyOrDecodeToJSON,
c0e8b12e
C
163 unwrapText
164}
165
166// ---------------------------------------------------------------------------
167
168function buildRequest (req: request.Test, options: CommonRequestParams) {
169 if (options.contentType) req.set('Accept', options.contentType)
170 if (options.token) req.set('Authorization', 'Bearer ' + options.token)
171 if (options.range) req.set('Range', options.range)
172 if (options.accept) req.set('Accept', options.accept)
173 if (options.host) req.set('Host', options.host)
174 if (options.redirects) req.redirects(options.redirects)
175 if (options.expectedStatus) req.expect(options.expectedStatus)
176 if (options.xForwardedFor) req.set('X-Forwarded-For', options.xForwardedFor)
177 if (options.type) req.type(options.type)
178
179 Object.keys(options.headers || {}).forEach(name => {
180 req.set(name, options.headers[name])
181 })
182
183 return req
184}
185
186function buildFields (req: request.Test, fields: { [ fieldName: string ]: any }, namespace?: string) {
187 if (!fields) return
188
189 let formKey: string
190
191 for (const key of Object.keys(fields)) {
192 if (namespace) formKey = `${namespace}[${key}]`
193 else formKey = key
194
195 if (fields[key] === undefined) continue
196
197 if (Array.isArray(fields[key]) && fields[key].length === 0) {
63436fc5 198 req.field(key, [])
c0e8b12e
C
199 continue
200 }
201
202 if (fields[key] !== null && typeof fields[key] === 'object') {
203 buildFields(req, fields[key], formKey)
204 } else {
205 req.field(formKey, fields[key])
206 }
207 }
0e1dc3e7 208}