import { createWriteStream, remove } from 'fs-extra'
-import got, { CancelableRequest, Options as GotOptions } from 'got'
+import got, { CancelableRequest, Options as GotOptions, RequestError } from 'got'
import { join } from 'path'
import { CONFIG } from '../initializers/config'
-import { ACTIVITY_PUB, PEERTUBE_VERSION, WEBSERVER } from '../initializers/constants'
+import { ACTIVITY_PUB, PEERTUBE_VERSION, REQUEST_TIMEOUT, WEBSERVER } from '../initializers/constants'
import { pipelinePromise } from './core-utils'
import { processImage } from './image-utils'
import { logger } from './logger'
+export interface PeerTubeRequestError extends Error {
+ statusCode?: number
+ responseBody?: any
+}
+
const httpSignature = require('http-signature')
type PeerTubeRequestOptions = {
key: string
headers: string[]
}
+ timeout?: number
jsonResponse?: boolean
} & Pick<GotOptions, 'headers' | 'json' | 'method' | 'searchParams'>
handlers: [
(options, next) => {
const promiseOrStream = next(options) as CancelableRequest<any>
- const bodyKBLimit = options.context?.bodyKBLimit
+ const bodyKBLimit = options.context?.bodyKBLimit as number
if (!bodyKBLimit) throw new Error('No KB limit for this request')
+ const bodyLimit = bodyKBLimit * 1000
+
/* eslint-disable @typescript-eslint/no-floating-promises */
promiseOrStream.on('downloadProgress', progress => {
- if (progress.transferred * 1000 > bodyKBLimit && progress.percent !== 1) {
- promiseOrStream.cancel(`Exceeded the download limit of ${bodyKBLimit} bytes`)
+ if (progress.transferred > bodyLimit && progress.percent !== 1) {
+ const message = `Exceeded the download limit of ${bodyLimit} B`
+ logger.warn(message)
+
+ // CancelableRequest
+ if (promiseOrStream.cancel) {
+ promiseOrStream.cancel()
+ return
+ }
+
+ // Stream
+ (promiseOrStream as any).destroy()
}
})
path
}, httpSignatureOptions)
}
+ },
+
+ (options: GotOptions) => {
+ options.timeout = REQUEST_TIMEOUT
}
]
}
let headers = options.headers || {}
- headers = { ...headers, date: new Date().toUTCString() }
+ if (!headers.date) {
+ headers = { ...headers, date: new Date().toUTCString() }
+ }
- if (activityPub) {
+ if (activityPub && !headers.accept) {
headers = { ...headers, accept: ACTIVITY_PUB.ACCEPT_HEADER }
}
method: options.method,
json: options.json,
searchParams: options.searchParams,
+ timeout: options.timeout ?? REQUEST_TIMEOUT,
headers,
context
}
}
-function buildRequestError (error: any) {
- const newError = new Error(error.message)
+function buildRequestError (error: RequestError) {
+ const newError: PeerTubeRequestError = new Error(error.message)
newError.name = error.name
newError.stack = error.stack
- if (error.response?.body) {
- error.responseBody = error.response.body
+ if (error.response) {
+ newError.responseBody = error.response.body
+ newError.statusCode = error.response.statusCode
}
return newError