15815213711
2024-08-26 67b8b6731811983447e053d4396b3708c14dfe3c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
import * as https from 'https';
import * as http from 'http';
import { IncomingHttpHeaders, OutgoingHttpHeaders } from 'http';
import * as url from 'url';
import { Readable, Writable } from 'stream';
import { EventEmitter } from 'events';
import { LookupFunction } from 'net';
 
export { IncomingHttpHeaders, OutgoingHttpHeaders };
export type HttpMethod = "GET" | "POST" | "DELETE" | "PUT" | "HEAD" | "OPTIONS" | "PATCH" | "TRACE" | "CONNECT"
  | "get" | "post" | "delete" | "put" | "head" | "options" | "patch" | "trace" | "connect";
 
export as namespace urllib;
export interface RequestOptions {
  /** Request method, defaults to GET. Could be GET, POST, DELETE or PUT. Alias 'type'. */
  method?: HttpMethod;
  /** Alias method  */
  type?: HttpMethod;
  /** Data to be sent. Will be stringify automatically. */
  data?: any;
  /** Force convert data to query string. */
  dataAsQueryString?: boolean;
  /** Manually set the content of payload. If set, data will be ignored. */
  content?: string | Buffer;
  /** Stream to be pipe to the remote.If set, data and content will be ignored. */
  stream?: Readable;
  /**
   * A writable stream to be piped by the response stream.
   * Responding data will be write to this stream and callback
   * will be called with data set null after finished writing.
   */
  writeStream?: Writable;
  /** consume the writeStream, invoke the callback after writeStream close. */
  consumeWriteStream?: boolean;
  /**
    * The files will send with multipart/form-data format, base on formstream.
    * If method not set, will use POST method by default.
    */
  files?: Array<Readable | Buffer | string> | object | Readable | Buffer | string;
  /** Type of request data.Could be json.If it's json, will auto set Content-Type: application/json header. */
  contentType?: string;
  /**
   * urllib default use querystring to stringify form data which don't support nested object,
   * will use qs instead of querystring to support nested object by set this option to true.
   */
  nestedQuerystring?: boolean;
  /**
   * Type of response data. Could be text or json.
   * If it's text, the callbacked data would be a String.
   * If it's json, the data of callback would be a parsed JSON Object
   * and will auto set Accept: application/json header. Default callbacked data would be a Buffer.
   */
  dataType?: string;
  /** Fix the control characters (U+0000 through U+001F) before JSON parse response. Default is false. */
  fixJSONCtlChars?: boolean;
  /** Request headers. */
  headers?: IncomingHttpHeaders;
  /** by default will convert header keys to lowercase */
  keepHeaderCase?: boolean;
  /**
   * Request timeout in milliseconds for connecting phase and response receiving phase.
   * Defaults to exports.
   * TIMEOUT, both are 5s.You can use timeout: 5000 to tell urllib use same timeout on two phase or set them seperately such as
   * timeout: [3000, 5000], which will set connecting timeout to 3s and response 5s.
   */
  timeout?: number | number[];
  /** username:password used in HTTP Basic Authorization. */
  auth?: string;
  /** username:password used in HTTP Digest Authorization. */
  digestAuth?: string;
  /** HTTP Agent object.Set false if you does not use agent. */
  agent?: http.Agent;
  /** HTTPS Agent object. Set false if you does not use agent. */
  httpsAgent?: https.Agent;
  /**
   * An array of strings or Buffers of trusted certificates.
   * If this is omitted several well known "root" CAs will be used, like VeriSign.
   * These are used to authorize connections.
   * Notes: This is necessary only if the server uses the self - signed certificate
   */
  ca?: string | Buffer | string[] | Buffer[];
  /**
   * If true, the server certificate is verified against the list of supplied CAs.
   * An 'error' event is emitted if verification fails.Default: true.
   */
  rejectUnauthorized?: boolean;
  /** A string or Buffer containing the private key, certificate and CA certs of the server in PFX or PKCS12 format. */
  pfx?: string | Buffer;
  /**
   * A string or Buffer containing the private key of the client in PEM format.
   * Notes: This is necessary only if using the client certificate authentication
   */
  key?: string | Buffer;
  /**
   * A string or Buffer containing the certificate key of the client in PEM format.
   * Notes: This is necessary only if using the client certificate authentication
   */
  cert?: string | Buffer;
  /** A string of passphrase for the private key or pfx. */
  passphrase?: string;
  /** A string describing the ciphers to use or exclude. */
  ciphers?: string;
  /** The SSL method to use, e.g.SSLv3_method to force SSL version 3. */
  secureProtocol?: string;
  /** follow HTTP 3xx responses as redirects. defaults to false. */
  followRedirect?: boolean;
  /** The maximum number of redirects to follow, defaults to 10. */
  maxRedirects?: number;
  /** Format the redirect url by your self. Default is url.resolve(from, to). */
  formatRedirectUrl?: (a: any, b: any) => void;
  /** Before request hook, you can change every thing here. */
  beforeRequest?: (...args: any[]) => void;
  /** let you get the res object when request connected, default false. alias customResponse */
  streaming?: boolean;
  /** Accept gzip response content and auto decode it, default is false. */
  gzip?: boolean;
  /** Enable timing or not, default is false. */
  timing?: boolean;
  /** Enable proxy request, default is false. */
  enableProxy?: boolean;
  /** proxy agent uri or options, default is null. */
  proxy?: string | { [key: string]: any };
  /**
   * Custom DNS lookup function, default is dns.lookup.
   * Require node >= 4.0.0(for http protocol) and node >=8(for https protocol)
   */
  lookup?: LookupFunction;
  /**
   * check request address to protect from SSRF and similar attacks.
   * It receive two arguments(ip and family) and should return true or false to identified the address is legal or not.
   * It rely on lookup and have the same version requirement.
   */
  checkAddress?: (ip: string, family: number | string, hostname: string) => boolean;
  /**
   * UNIX domain socket path. (Windows is not supported)
   */
  socketPath?: string;
}
 
export interface HttpClientResponse<T> {
  data: T;
  status: number;
  headers:  OutgoingHttpHeaders;
  res: http.IncomingMessage & {
    /**
     * https://eggjs.org/en/core/httpclient.html#timing-boolean
     */
    timing?: {
      queuing: number;
      dnslookup: number;
      connected: number;
      requestSent: number;
      waiting: number;
      contentDownload: number;
    }
  };
}
 
 
/**
 * @param data Outgoing message
 * @param res http response
 */
export type Callback<T> = (err: Error, data: T, res: http.IncomingMessage) => void;
 
/**
 * Handle all http request, both http and https support well.
 *
 * @example
 * // GET http://httptest.cnodejs.net
 * urllib.request('http://httptest.cnodejs.net/test/get', function(err, data, res) {});
 * // POST http://httptest.cnodejs.net
 * var args = { type: 'post', data: { foo: 'bar' } };
 * urllib.request('http://httptest.cnodejs.net/test/post', args, function(err, data, res) {});
 *
 * @param url The URL to request, either a String or a Object that return by url.parse.
 */
export function request<T = any>(url: string | url.URL, options?: RequestOptions): Promise<HttpClientResponse<T>>;
/**
 * @param url The URL to request, either a String or a Object that return by url.parse.
 */
export function request<T = any>(url: string | url.URL, callback: Callback<T>): void;
/**
 * @param url The URL to request, either a String or a Object that return by url.parse.
 */
export function request<T = any>(url: string | url.URL, options: RequestOptions, callback: Callback<T>): void;
 
/**
 * Handle request with a callback.
 * @param url The URL to request, either a String or a Object that return by url.parse.
 */
export function requestWithCallback<T = any>(url: string | url.URL, callback: Callback<T>): void;
/**
 * @param url The URL to request, either a String or a Object that return by url.parse.
 */
export function requestWithCallback<T = any>(url: string | url.URL, options: RequestOptions, callback: Callback<T>): void;
 
/**
 * yield urllib.requestThunk(url, args)
 * @param url The URL to request, either a String or a Object that return by url.parse.
 */
export function requestThunk<T = any>(url: string | url.URL, options?: RequestOptions): (callback: Callback<T>) => void;
 
/**
 * alias to request.
 * Handle all http request, both http and https support well.
 *
 * @example
 * // GET http://httptest.cnodejs.net
 * urllib.request('http://httptest.cnodejs.net/test/get', function(err, data, res) {});
 * // POST http://httptest.cnodejs.net
 * var args = { type: 'post', data: { foo: 'bar' } };
 * urllib.request('http://httptest.cnodejs.net/test/post', args, function(err, data, res) {});
 *
 * @param url The URL to request, either a String or a Object that return by url.parse.
 * @param options Optional, @see RequestOptions.
 */
export function curl<T = any>(url: string | url.URL, options?: RequestOptions): Promise<HttpClientResponse<T>>;
/**
 * @param url The URL to request, either a String or a Object that return by url.parse.
 */
export function curl<T = any>(url: string | url.URL, callback: Callback<T>): void;
/**
 * @param url The URL to request, either a String or a Object that return by url.parse.
 */
export function curl<T = any>(url: string | url.URL, options: RequestOptions, callback: Callback<T>): void;
/**
 * The default request timeout(in milliseconds).
 */
export const TIMEOUT: number;
/**
 * The default request & response timeout(in milliseconds).
 */
export const TIMEOUTS: [number, number];
 
/**
 * Request user agent.
 */
export const USER_AGENT: string;
 
/**
 * Request http agent.
 */
export const agent: http.Agent;
 
/**
 * Request https agent.
 */
export const httpsAgent: https.Agent;
 
export class HttpClient<O extends RequestOptions = RequestOptions> extends EventEmitter {
  request<T = any>(url: string | url.URL): Promise<HttpClientResponse<T>>;
  request<T = any>(url: string | url.URL, options: O): Promise<HttpClientResponse<T>>;
  request<T = any>(url: string | url.URL, callback: Callback<T>): void;
  request<T = any>(url: string | url.URL, options: O, callback: Callback<T>): void;
 
  curl<T = any>(url: string | url.URL, options: O): Promise<HttpClientResponse<T>>;
  curl<T = any>(url: string | url.URL): Promise<HttpClientResponse<T>>;
  curl<T = any>(url: string | url.URL, callback: Callback<T>): void;
  curl<T = any>(url: string | url.URL, options: O, callback: Callback<T>): void;
 
  requestThunk(url: string | url.URL, options?: O): (callback: (...args: any[]) => void) => void;
}
 
export interface RequestOptions2 extends RequestOptions {
  retry?: number;
  retryDelay?: number;
  isRetry?: (res: HttpClientResponse<any>) => boolean;
}
 
/**
 * request method only return a promise,
 * compatible with async/await and generator in co.
 */
export class HttpClient2 extends HttpClient<RequestOptions2> {}
 
/**
 * Create a HttpClient instance.
 */
export function create(options?: RequestOptions): HttpClient;