-import * as replay from 'request-replay'
-import * as request from 'request'
-
-import {
- RETRY_REQUESTS,
- REMOTE_SCHEME,
- CONFIG
-} from '../initializers'
-import { sign } from './peertube-crypto'
-
-function makeRetryRequest (params, callback) {
- replay(
- request(params, callback),
- {
- retries: RETRY_REQUESTS,
- factor: 3,
- maxTimeout: Infinity,
- errorCodes: [ 'EADDRINFO', 'ETIMEDOUT', 'ECONNRESET', 'ESOCKETTIMEDOUT', 'ENOTFOUND', 'ECONNREFUSED' ]
+import { createWriteStream, remove } from 'fs-extra'
+import got, { CancelableRequest, NormalizedOptions, Options as GotOptions, RequestError, Response } from 'got'
+import { HttpProxyAgent, HttpsProxyAgent } from 'hpagent'
+import { join } from 'path'
+import { CONFIG } from '../initializers/config'
+import { ACTIVITY_PUB, BINARY_CONTENT_TYPES, PEERTUBE_VERSION, REQUEST_TIMEOUTS, WEBSERVER } from '../initializers/constants'
+import { pipelinePromise } from './core-utils'
+import { processImage } from './image-utils'
+import { logger, loggerTagsFactory } from './logger'
+import { getProxy, isProxyEnabled } from './proxy'
+
+const lTags = loggerTagsFactory('request')
+
+const httpSignature = require('@peertube/http-signature')
+
+export interface PeerTubeRequestError extends Error {
+ statusCode?: number
+ responseBody?: any
+ responseHeaders?: any
+}
+
+type PeerTubeRequestOptions = {
+ timeout?: number
+ activityPub?: boolean
+ bodyKBLimit?: number // 1MB
+ httpSignature?: {
+ algorithm: string
+ authorizationHeaderName: string
+ keyId: string
+ key: string
+ headers: string[]
+ }
+ jsonResponse?: boolean
+} & Pick<GotOptions, 'headers' | 'json' | 'method' | 'searchParams'>
+
+const peertubeGot = got.extend({
+ ...getAgent(),
+
+ headers: {
+ 'user-agent': getUserAgent()
+ },
+
+ handlers: [
+ (options, next) => {
+ const promiseOrStream = next(options) as CancelableRequest<any>
+ 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 > bodyLimit && progress.percent !== 1) {
+ const message = `Exceeded the download limit of ${bodyLimit} B`
+ logger.warn(message, lTags())
+
+ // CancelableRequest
+ if (promiseOrStream.cancel) {
+ promiseOrStream.cancel()
+ return
+ }
+
+ // Stream
+ (promiseOrStream as any).destroy()
+ }
+ })
+
+ return promiseOrStream