]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/helpers/requests.ts
Translated using Weblate (Vietnamese)
[github/Chocobozzz/PeerTube.git] / server / helpers / requests.ts
index 2c9da213c112068a666c431ad50d7e586210f5bc..d3c83d26e29f25dc78ac884e3cda2c3a2003e17e 100644 (file)
@@ -1,12 +1,17 @@
 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 = {
@@ -19,6 +24,7 @@ type PeerTubeRequestOptions = {
     key: string
     headers: string[]
   }
+  timeout?: number
   jsonResponse?: boolean
 } & Pick<GotOptions, 'headers' | 'json' | 'method' | 'searchParams'>
 
@@ -30,13 +36,25 @@ const peertubeGot = got.extend({
   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()
         }
       })
 
@@ -75,6 +93,10 @@ const peertubeGot = got.extend({
             path
           }, httpSignatureOptions)
         }
+      },
+
+      (options: GotOptions) => {
+        options.timeout = REQUEST_TIMEOUT
       }
     ]
   }
@@ -153,9 +175,11 @@ function buildGotOptions (options: PeerTubeRequestOptions) {
 
   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 }
   }
 
@@ -163,18 +187,20 @@ function buildGotOptions (options: PeerTubeRequestOptions) {
     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