import { URL } from 'url';
import tls from 'tls';
import net from 'net';
import http from 'http';
import { EventEmitter } from 'events';
import { IHttpRequest, HttpRequest } from '../../models/HttpRequest.js';
import { IRequestBaseConfig } from '../../models/RequestConfig.js';
import { IRequestAuthorization } from '../../models/RequestAuthorization.js';
import { HttpCertificate } from '../../models/ClientCertificate.js';
import { SentRequest } from '../../models/SentRequest.js';
import { Response } from '../../models/Response.js';
import { ResponseRedirect } from '../../models/ResponseRedirect.js';
import { RequestLog, IRequestLog } from '../../models/RequestLog.js';
import { RequestTime } from '../../models/RequestTime.js';
import { SerializableError } from '../../models/SerializableError.js';
import { ResponseAuthorization } from '../../models/ResponseAuthorization.js';
import { ILogger, Logger } from '../../lib/logging/Logger.js';
import { Headers } from '../../lib/headers/Headers.js';
import * as RequestUtils from './RequestUtils.js';
/**
 * A note on cookies and redirects.
 * The architecture here assumes running requests is a test environment.
 * This means cookies are not processed by this class. This includes processing cookies during a redirect.
 * The class does parse response cookies before a redirect and sets new cookies in the redirected request only
 * if they match the domain + path. However, this class doesn't know anything about other cookies
 * that the application may have for the domain after redirection.
 */
export interface HttpEngineOptions extends IRequestBaseConfig {
    /**
     * The authorization configuration to apply to the request.
     */
    authorization?: IRequestAuthorization[];
    /**
     * Logger object.
     */
    logger?: ILogger;
    /**
     * A certificate to use with the request.
     */
    certificates?: HttpCertificate[];
}
export interface RequestStats {
    firstReceiveTime?: number;
    lastReceivedTime?: number;
    messageStart?: number;
    sentTime?: number;
    connectionTime?: number;
    lookupTime?: number;
    connectedTime?: number;
    secureStartTime?: number;
    secureConnectedTime?: number;
    startTime?: number;
    responseTime?: number;
    receivingTime?: number;
}
export interface ResponseErrorInit {
    code?: number | string;
    message?: string;
}
export interface BeforeRedirectDetail {
    location: string;
    returnValue: boolean;
}
export interface HeadersReceivedDetail {
    value: string;
    returnValue: boolean;
}
export interface IRequestAuthState {
    method: 'ntlm';
    state: number;
    headers?: string;
    challengeHeader?: string;
}
export declare interface HttpEngine {
    /**
     * Dispatched before a redirect occurs.
     * The detail object on the listener's only argument has the `location` property
     * with the new location for the request.
     * When the `returnValue` is set to `false` the request is cancelled.
     */
    on(event: 'beforeredirect', listener: (detail: BeforeRedirectDetail) => void): this;
    on(event: 'loadstart' | 'firstbyte' | 'loadend', listener: () => void): this;
    on(event: 'headersreceived', listener: (detail: HeadersReceivedDetail) => void): this;
    /**
     * Dispatched before a redirect occurs.
     * The detail object on the listener's only argument has the `location` property
     * with the new location for the request.
     * When the `returnValue` is set to `false` the request is cancelled.
     */
    once(event: 'beforeredirect', listener: (detail: BeforeRedirectDetail) => void): this;
    once(event: 'loadstart' | 'firstbyte' | 'loadend', listener: () => void): this;
    once(event: 'headersreceived', listener: (detail: HeadersReceivedDetail) => void): this;
}
export declare const mainPromiseSymbol: unique symbol;
/**
 * The base class to make HTTP requests in API Client.
 * This can be extended to support particular implementations.
 */
export declare abstract class HttpEngine extends EventEmitter {
    request: HttpRequest;
    opts: HttpEngineOptions;
    logger: Logger;
    /**
     * The current sent request
     */
    sentRequest: SentRequest;
    redirects: ResponseRedirect[];
    /**
     * When true the request has been aborted.
     */
    aborted: boolean;
    /**
     * Parsed value of the request URL.
     */
    uri: URL;
    socket?: net.Socket;
    /**
     * Host header can be different than registered URL because of
     * `hosts` rules.
     * If a rule changes host value of the URL the original URL host value
     * is used when generating the request and not overwritten one.
     * This way virtual hosts can be tested using hosts.
     */
    hostHeader: string | undefined;
    protected hostTestReg: RegExp;
    /**
     * Set when the request is redirected.
     */
    redirecting: boolean;
    /**
     * The response headers.
     * The object may be empty when the response is not set.
     */
    currentHeaders: Headers;
    /**
     * The response object build during the execution.
     */
    currentResponse?: Response;
    /**
     * @return True if following redirects is allowed.
     */
    get followRedirects(): boolean;
    /**
     * The request timeout.
     */
    get timeout(): number;
    /**
     * Keeps the raw body in a temporary buffer while processing the response.
     */
    _rawBody?: Buffer;
    stats: RequestStats;
    auth?: IRequestAuthState;
    protected mainResolver?: (log: IRequestLog) => void;
    protected mainRejecter?: (err: SerializableError) => void;
    [mainPromiseSymbol]?: Promise<IRequestLog>;
    protected _signal?: AbortSignal;
    /**
     * The abort signal to set on this request.
     * Aborts the request when the signal fires.
     * @type {(AbortSignal | undefined)}
     */
    get signal(): AbortSignal | undefined;
    set signal(value: AbortSignal | undefined);
    constructor(request: IHttpRequest, opts?: HttpEngineOptions);
    /**
     * Creates a logger object to log debug output.
     */
    setupLogger(opts?: HttpEngineOptions): Logger;
    /**
     * Updates the `uri` property from current request URL
     * @param value The request URL
     */
    readUrl(value: string): URL;
    /**
     * Aborts current request.
     * It emits `error` event
     */
    abort(): void;
    /**
     * Handler for the `abort` event on the `AbortSignal`.
     */
    protected _abortHandler(): void;
    /**
     * Sends the request.
     */
    abstract send(): Promise<IRequestLog>;
    /**
     * Decompresses received body if `content-encoding` header is set.
     *
     * @param body A body buffer to decompress.
     * @return Promise resolved to parsed body
     */
    decompress(body?: Buffer): Promise<Buffer | undefined>;
    /**
     * Decompress body with Inflate.
     * @param body Received response payload
     * @return Promise resolved to decompressed buffer.
     */
    inflate(body: Buffer): Promise<Buffer>;
    /**
     * Decompress body with ZLib.
     * @param body Received response payload
     * @return Promise resolved to decompressed buffer.
     */
    gunzip(body: Buffer): Promise<Buffer>;
    /**
     * Decompress Brotli.
     * @param body Received response payload
     * @return Promise resolved to decompressed buffer.
     */
    brotli(body: Buffer): Promise<Buffer>;
    /**
     * Prepares headers list to be send to the remote machine.
     * If `defaultHeaders` option is set then it adds `user-agent` and `accept`
     * headers.
     * @param headers Parsed headers
     * @param withPayload Whether the request should send a body message
     */
    prepareHeaders(headers: Headers, withPayload?: boolean): void;
    /**
     * Cleans the state after finished.
     */
    _cleanUp(): void;
    /**
     * Cleans up the state for redirect.
     */
    _cleanUpRedirect(): void;
    /**
     * Reports response when redirected.
     * @param status Received status code
     * @return True if the request has been redirected.
     */
    _reportRedirect(status: number): boolean;
    /**
     * Creates a response and adds it to the redirects list and redirects
     * the request to the new location.
     */
    _redirectRequest(options: RequestUtils.RedirectOptions): Promise<void>;
    /**
     * @param location The redirect location.
     * @return Redirect response object
     */
    _createRedirectResponse(location: string): Promise<ResponseRedirect>;
    /**
     * Creates a response object
     *
     * @return A response object.
     */
    _createResponse(): Promise<Response | undefined>;
    /**
     * Finishes the response with error message.
     */
    _errorRequest(opts: ResponseErrorInit): void;
    /**
     * Generates authorization info object from response.
     */
    _getAuth(): ResponseAuthorization;
    /**
     * Generate response object and publish it to the listeners.
     */
    _publishResponse(): Promise<void>;
    /**
     * Creates HAR 1.2 timings object from stats.
     * @param stats Timings object
     */
    _computeStats(stats: RequestStats): RequestTime;
    /**
     * Handles cookie exchange when redirecting the request.
     * @param responseCookies Cookies received in the response
     * @param location Redirect destination
     */
    _processRedirectCookies(responseCookies: string, location: string): void;
    /**
     * Checks certificate identity using TLS api.
     *
     * @param host Request host name
     * @param cert TLS certificate info object
     */
    _checkServerIdentity(host: string, cert: tls.PeerCertificate): Error | undefined;
    /**
     * Clears event listeners of the socket object,
     */
    _clearSocketEventListeners(): void;
    /**
     * Adds client certificate to the request configuration options.
     *
     * @param certificate List of certificate configurations.
     * @param options Request options. Cert agent options are added to this object.
     */
    _addClientCertificate(certificate: HttpCertificate, options: tls.ConnectionOptions): void;
    /**
     * @return Proxy authorization header value, when defined.
     */
    _proxyAuthHeader(): string | undefined;
    /**
     * Reads the raw headers from the node response and transforms them into the internal headers.
     */
    computeResponseHeaders(res: http.IncomingMessage): Headers;
    /**
     * Called with the `send()` function to initialize the main promise returned by the send function.
     * The send function returns a promise that is resolved when the request finish.
     */
    protected wrapExecution(): Promise<IRequestLog>;
    /**
     * Called by the request finalizer or error finalized to report the response.
     *
     * @param log Either the request execution log or an error.
     */
    protected finalizeRequest(log: RequestLog | SerializableError): void;
}
//# sourceMappingURL=HttpEngine.d.ts.map