/*
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/**
 * @implements {Common.ContentProvider}
 * @unrestricted
 */
export default class NetworkRequest extends Common.Object {
  /**
   * @param {!Protocol.Network.RequestId} requestId
   * @param {string} url
   * @param {string} documentURL
   * @param {!Protocol.Page.FrameId} frameId
   * @param {!Protocol.Network.LoaderId} loaderId
   * @param {?Protocol.Network.Initiator} initiator
   */
  constructor(requestId, url, documentURL, frameId, loaderId, initiator) {
    super();

    this._requestId = requestId;
    this._backendRequestId = requestId;
    this.setUrl(url);
    this._documentURL = documentURL;
    this._frameId = frameId;
    this._loaderId = loaderId;
    /** @type {?Protocol.Network.Initiator} */
    this._initiator = initiator;
    /** @type {?NetworkRequest} */
    this._redirectSource = null;
    /** @type {?NetworkRequest} */
    this._redirectDestination = null;
    this._issueTime = -1;
    this._startTime = -1;
    this._endTime = -1;
    /** @type {!Protocol.Network.BlockedReason|undefined} */
    this._blockedReason = undefined;

    this.statusCode = 0;
    this.statusText = '';
    this.requestMethod = '';
    this.requestTime = 0;
    /** @type {string} */
    this.protocol = '';
    /** @type {!Protocol.Security.MixedContentType} */
    this.mixedContentType = Protocol.Security.MixedContentType.None;

    /** @type {?Protocol.Network.ResourcePriority} */
    this._initialPriority = null;
    /** @type {?Protocol.Network.ResourcePriority} */
    this._currentPriority = null;

    /** @type {?Protocol.Network.SignedExchangeInfo} */
    this._signedExchangeInfo = null;

    /** @type {!Common.ResourceType} */
    this._resourceType = Common.resourceTypes.Other;
    /** @type {?Promise<!SDK.NetworkRequest.ContentData>} */
    this._contentData = null;
    /** @type {!Array.<!SDK.NetworkRequest.WebSocketFrame>} */
    this._frames = [];
    /** @type {!Array.<!SDK.NetworkRequest.EventSourceMessage>} */
    this._eventSourceMessages = [];

    /** @type {!Object<string, (string|undefined)>} */
    this._responseHeaderValues = {};
    this._responseHeadersText = '';

    /** @type {!Array<!SDK.NetworkRequest.NameValue>} */
    this._requestHeaders = [];
    /** @type {!Object<string, (string|undefined)>} */
    this._requestHeaderValues = {};

    this._remoteAddress = '';

    /** @type {?Protocol.Network.RequestReferrerPolicy} */
    this._referrerPolicy = null;

    /** @type {!Protocol.Security.SecurityState} */
    this._securityState = Protocol.Security.SecurityState.Unknown;
    /** @type {?Protocol.Network.SecurityDetails} */
    this._securityDetails = null;

    /** @type {string} */
    this.connectionId = '0';
    /** @type {?Promise<?Array.<!SDK.NetworkRequest.NameValue>>} */
    this._formParametersPromise = null;
    // Assume no body initially
    /** @type {?Promise<?string>} */
    this._requestFormDataPromise = /** @type {?Promise<?string>} */ (Promise.resolve(null));

    /** @type {boolean} */
    this._hasExtraRequestInfo = false;
    /** @type {boolean} */
    this._hasExtraResponseInfo = false;

    /** @type {!Array<!SDK.NetworkRequest.BlockedCookieWithReason>} */
    this._blockedRequestCookies = [];
    /** @type {!Array<!SDK.NetworkRequest.BlockedSetCookieWithReason>} */
    this._blockedResponseCookies = [];
  }

  /**
   * @param {!NetworkRequest} other
   * @return {number}
   */
  indentityCompare(other) {
    const thisId = this.requestId();
    const thatId = other.requestId();
    if (thisId > thatId) {
      return 1;
    }
    if (thisId < thatId) {
      return -1;
    }
    return 0;
  }

  /**
   * @return {!Protocol.Network.RequestId}
   */
  requestId() {
    return this._requestId;
  }

  /**
   * @return {!Protocol.Network.RequestId}
   */
  backendRequestId() {
    return this._backendRequestId;
  }

  /**
   * @return {string}
   */
  url() {
    return this._url;
  }

  /**
   * @return {boolean}
   */
  isBlobRequest() {
    return this._url.startsWith('blob:');
  }

  /**
   * @param {string} x
   */
  setUrl(x) {
    if (this._url === x) {
      return;
    }

    this._url = x;
    this._parsedURL = new Common.ParsedURL(x);
    delete this._queryString;
    delete this._parsedQueryParameters;
    delete this._name;
    delete this._path;
  }

  /**
   * @return {string}
   */
  get documentURL() {
    return this._documentURL;
  }

  get parsedURL() {
    return this._parsedURL;
  }

  /**
   * @return {!Protocol.Page.FrameId}
   */
  get frameId() {
    return this._frameId;
  }

  /**
   * @return {!Protocol.Network.LoaderId}
   */
  get loaderId() {
    return this._loaderId;
  }

  /**
   * @param {string} ip
   * @param {number} port
   */
  setRemoteAddress(ip, port) {
    this._remoteAddress = ip + ':' + port;
    this.dispatchEventToListeners(Events.RemoteAddressChanged, this);
  }

  /**
   * @return {string}
   */
  remoteAddress() {
    return this._remoteAddress;
  }

  /**
   * @param {!Protocol.Network.RequestReferrerPolicy} referrerPolicy
   */
  setReferrerPolicy(referrerPolicy) {
    this._referrerPolicy = referrerPolicy;
  }

  /**
   * @return {?Protocol.Network.RequestReferrerPolicy}
   */
  referrerPolicy() {
    return this._referrerPolicy;
  }

  /**
   * @return {!Protocol.Security.SecurityState}
   */
  securityState() {
    return this._securityState;
  }

  /**
   * @param {!Protocol.Security.SecurityState} securityState
   */
  setSecurityState(securityState) {
    this._securityState = securityState;
  }

  /**
   * @return {?Protocol.Network.SecurityDetails}
   */
  securityDetails() {
    return this._securityDetails;
  }

  /**
   * @param {!Protocol.Network.SecurityDetails} securityDetails
   */
  setSecurityDetails(securityDetails) {
    this._securityDetails = securityDetails;
  }

  /**
   * @return {number}
   */
  get startTime() {
    return this._startTime || -1;
  }

  /**
   * @param {number} monotonicTime
   * @param {number} wallTime
   */
  setIssueTime(monotonicTime, wallTime) {
    this._issueTime = monotonicTime;
    this._wallIssueTime = wallTime;
    this._startTime = monotonicTime;
  }

  /**
   * @return {number}
   */
  issueTime() {
    return this._issueTime;
  }

  /**
   * @param {number} monotonicTime
   * @return {number}
   */
  pseudoWallTime(monotonicTime) {
    return this._wallIssueTime ? this._wallIssueTime - this._issueTime + monotonicTime : monotonicTime;
  }

  /**
   * @return {number}
   */
  get responseReceivedTime() {
    return this._responseReceivedTime || -1;
  }

  /**
   * @param {number} x
   */
  set responseReceivedTime(x) {
    this._responseReceivedTime = x;
  }

  /**
   * @return {number}
   */
  get endTime() {
    return this._endTime || -1;
  }

  /**
   * @param {number} x
   */
  set endTime(x) {
    if (this.timing && this.timing.requestTime) {
      // Check against accurate responseReceivedTime.
      this._endTime = Math.max(x, this.responseReceivedTime);
    } else {
      // Prefer endTime since it might be from the network stack.
      this._endTime = x;
      if (this._responseReceivedTime > x) {
        this._responseReceivedTime = x;
      }
    }
    this.dispatchEventToListeners(Events.TimingChanged, this);
  }

  /**
   * @return {number}
   */
  get duration() {
    if (this._endTime === -1 || this._startTime === -1) {
      return -1;
    }
    return this._endTime - this._startTime;
  }

  /**
   * @return {number}
   */
  get latency() {
    if (this._responseReceivedTime === -1 || this._startTime === -1) {
      return -1;
    }
    return this._responseReceivedTime - this._startTime;
  }

  /**
   * @return {number}
   */
  get resourceSize() {
    return this._resourceSize || 0;
  }

  /**
   * @param {number} x
   */
  set resourceSize(x) {
    this._resourceSize = x;
  }

  /**
   * @return {number}
   */
  get transferSize() {
    return this._transferSize || 0;
  }

  /**
   * @param {number} x
   */
  increaseTransferSize(x) {
    this._transferSize = (this._transferSize || 0) + x;
  }

  /**
   * @param {number} x
   */
  setTransferSize(x) {
    this._transferSize = x;
  }

  /**
   * @return {boolean}
   */
  get finished() {
    return this._finished;
  }

  /**
   * @param {boolean} x
   */
  set finished(x) {
    if (this._finished === x) {
      return;
    }

    this._finished = x;

    if (x) {
      this.dispatchEventToListeners(Events.FinishedLoading, this);
    }
  }

  /**
   * @return {boolean}
   */
  get failed() {
    return this._failed;
  }

  /**
   * @param {boolean} x
   */
  set failed(x) {
    this._failed = x;
  }

  /**
   * @return {boolean}
   */
  get canceled() {
    return this._canceled;
  }

  /**
   * @param {boolean} x
   */
  set canceled(x) {
    this._canceled = x;
  }

  /**
   * @return {!Protocol.Network.BlockedReason|undefined}
   */
  blockedReason() {
    return this._blockedReason;
  }

  /**
   * @param {!Protocol.Network.BlockedReason} reason
   */
  setBlockedReason(reason) {
    this._blockedReason = reason;
  }

  /**
   * @return {boolean}
   */
  wasBlocked() {
    return !!this._blockedReason;
  }

  /**
   * @return {boolean}
   */
  cached() {
    return (!!this._fromMemoryCache || !!this._fromDiskCache) && !this._transferSize;
  }

  /**
   * @return {boolean}
   */
  cachedInMemory() {
    return !!this._fromMemoryCache && !this._transferSize;
  }

  /**
   * @return {boolean}
   */
  fromPrefetchCache() {
    return !!this._fromPrefetchCache;
  }

  setFromMemoryCache() {
    this._fromMemoryCache = true;
    delete this._timing;
  }

  setFromDiskCache() {
    this._fromDiskCache = true;
  }

  setFromPrefetchCache() {
    this._fromPrefetchCache = true;
  }

  /**
   * Returns true if the request was intercepted by a service worker and it
   * provided its own response.
   * @return {boolean}
   */
  get fetchedViaServiceWorker() {
    return !!this._fetchedViaServiceWorker;
  }

  /**
   * @param {boolean} x
   */
  set fetchedViaServiceWorker(x) {
    this._fetchedViaServiceWorker = x;
  }

  /**
   * Returns true if the request was sent by a service worker.
   * @return {boolean}
   */
  initiatedByServiceWorker() {
    const networkManager = SDK.NetworkManager.forRequest(this);
    if (!networkManager) {
      return false;
    }
    return networkManager.target().type() === SDK.Target.Type.ServiceWorker;
  }

  /**
   * @return {!Protocol.Network.ResourceTiming|undefined}
   */
  get timing() {
    return this._timing;
  }

  /**
   * @param {!Protocol.Network.ResourceTiming|undefined} timingInfo
   */
  set timing(timingInfo) {
    if (!timingInfo || this._fromMemoryCache) {
      return;
    }
    // Take startTime and responseReceivedTime from timing data for better accuracy.
    // Timing's requestTime is a baseline in seconds, rest of the numbers there are ticks in millis.
    this._startTime = timingInfo.requestTime;
    const headersReceivedTime = timingInfo.requestTime + timingInfo.receiveHeadersEnd / 1000.0;
    if ((this._responseReceivedTime || -1) < 0 || this._responseReceivedTime > headersReceivedTime) {
      this._responseReceivedTime = headersReceivedTime;
    }
    if (this._startTime > this._responseReceivedTime) {
      this._responseReceivedTime = this._startTime;
    }

    this._timing = timingInfo;
    this.dispatchEventToListeners(Events.TimingChanged, this);
  }

  /**
   * @return {string}
   */
  get mimeType() {
    return this._mimeType;
  }

  /**
   * @param {string} x
   */
  set mimeType(x) {
    this._mimeType = x;
  }

  /**
   * @return {string}
   */
  get displayName() {
    return this._parsedURL.displayName;
  }

  /**
   * @return {string}
   */
  name() {
    if (this._name) {
      return this._name;
    }
    this._parseNameAndPathFromURL();
    return this._name;
  }

  /**
   * @return {string}
   */
  path() {
    if (this._path) {
      return this._path;
    }
    this._parseNameAndPathFromURL();
    return this._path;
  }

  _parseNameAndPathFromURL() {
    if (this._parsedURL.isDataURL()) {
      this._name = this._parsedURL.dataURLDisplayName();
      this._path = '';
    } else if (this._parsedURL.isBlobURL()) {
      this._name = this._parsedURL.url;
      this._path = '';
    } else if (this._parsedURL.isAboutBlank()) {
      this._name = this._parsedURL.url;
      this._path = '';
    } else {
      this._path = this._parsedURL.host + this._parsedURL.folderPathComponents;

      const networkManager = SDK.NetworkManager.forRequest(this);
      const inspectedURL = networkManager ? networkManager.target().inspectedURL().asParsedURL() : null;
      this._path = this._path.trimURL(inspectedURL ? inspectedURL.host : '');
      if (this._parsedURL.lastPathComponent || this._parsedURL.queryParams) {
        this._name =
            this._parsedURL.lastPathComponent + (this._parsedURL.queryParams ? '?' + this._parsedURL.queryParams : '');
      } else if (this._parsedURL.folderPathComponents) {
        this._name =
            this._parsedURL.folderPathComponents.substring(this._parsedURL.folderPathComponents.lastIndexOf('/') + 1) +
            '/';
        this._path = this._path.substring(0, this._path.lastIndexOf('/'));
      } else {
        this._name = this._parsedURL.host;
        this._path = '';
      }
    }
  }

  /**
   * @return {string}
   */
  get folder() {
    let path = this._parsedURL.path;
    const indexOfQuery = path.indexOf('?');
    if (indexOfQuery !== -1) {
      path = path.substring(0, indexOfQuery);
    }
    const lastSlashIndex = path.lastIndexOf('/');
    return lastSlashIndex !== -1 ? path.substring(0, lastSlashIndex) : '';
  }

  /**
   * @return {string}
   */
  get pathname() {
    return this._parsedURL.path;
  }

  /**
   * @return {!Common.ResourceType}
   */
  resourceType() {
    return this._resourceType;
  }

  /**
   * @param {!Common.ResourceType} resourceType
   */
  setResourceType(resourceType) {
    this._resourceType = resourceType;
  }

  /**
   * @return {string}
   */
  get domain() {
    return this._parsedURL.host;
  }

  /**
   * @return {string}
   */
  get scheme() {
    return this._parsedURL.scheme;
  }

  /**
   * @return {?NetworkRequest}
   */
  redirectSource() {
    return this._redirectSource;
  }

  /**
   * @param {?NetworkRequest} originatingRequest
   */
  setRedirectSource(originatingRequest) {
    this._redirectSource = originatingRequest;
  }

  /**
   * @return {?NetworkRequest}
   */
  redirectDestination() {
    return this._redirectDestination;
  }

  /**
   * @param {?NetworkRequest} redirectDestination
   */
  setRedirectDestination(redirectDestination) {
    this._redirectDestination = redirectDestination;
  }

  /**
   * @return {!Array.<!SDK.NetworkRequest.NameValue>}
   */
  requestHeaders() {
    return this._requestHeaders;
  }

  /**
   * @param {!Array.<!SDK.NetworkRequest.NameValue>} headers
   */
  setRequestHeaders(headers) {
    this._requestHeaders = headers;
    delete this._requestCookies;

    this.dispatchEventToListeners(Events.RequestHeadersChanged);
  }

  /**
   * @return {string|undefined}
   */
  requestHeadersText() {
    return this._requestHeadersText;
  }

  /**
   * @param {string} text
   */
  setRequestHeadersText(text) {
    this._requestHeadersText = text;

    this.dispatchEventToListeners(Events.RequestHeadersChanged);
  }

  /**
   * @param {string} headerName
   * @return {string|undefined}
   */
  requestHeaderValue(headerName) {
    if (this._requestHeaderValues[headerName]) {
      return this._requestHeaderValues[headerName];
    }
    this._requestHeaderValues[headerName] = this._computeHeaderValue(this.requestHeaders(), headerName);
    return this._requestHeaderValues[headerName];
  }

  /**
   * @return {?Array.<!SDK.Cookie>}
   */
  get requestCookies() {
    if (!this._requestCookies) {
      this._requestCookies = SDK.CookieParser.parseCookie(this.requestHeaderValue('Cookie'));
    }
    return this._requestCookies;
  }

  /**
   * @return {!Promise<?string>}
   */
  requestFormData() {
    if (!this._requestFormDataPromise) {
      this._requestFormDataPromise = SDK.NetworkManager.requestPostData(this);
    }
    return this._requestFormDataPromise;
  }

  /**
   * @param {boolean} hasData
   * @param {?string} data
   */
  setRequestFormData(hasData, data) {
    this._requestFormDataPromise = (hasData && data === null) ? null : Promise.resolve(data);
    this._formParametersPromise = null;
  }

  /**
   * @return {string}
   */
  _filteredProtocolName() {
    const protocol = this.protocol.toLowerCase();
    if (protocol === 'h2') {
      return 'http/2.0';
    }
    return protocol.replace(/^http\/2(\.0)?\+/, 'http/2.0+');
  }

  /**
   * @return {string}
   */
  requestHttpVersion() {
    const headersText = this.requestHeadersText();
    if (!headersText) {
      const version = this.requestHeaderValue('version') || this.requestHeaderValue(':version');
      if (version) {
        return version;
      }
      return this._filteredProtocolName();
    }
    const firstLine = headersText.split(/\r\n/)[0];
    const match = firstLine.match(/(HTTP\/\d+\.\d+)$/);
    return match ? match[1] : 'HTTP/0.9';
  }

  /**
   * @return {!Array.<!SDK.NetworkRequest.NameValue>}
   */
  get responseHeaders() {
    return this._responseHeaders || [];
  }

  /**
   * @param {!Array.<!SDK.NetworkRequest.NameValue>} x
   */
  set responseHeaders(x) {
    this._responseHeaders = x;
    delete this._sortedResponseHeaders;
    delete this._serverTimings;
    delete this._responseCookies;
    this._responseHeaderValues = {};

    this.dispatchEventToListeners(Events.ResponseHeadersChanged);
  }

  /**
   * @return {string}
   */
  get responseHeadersText() {
    return this._responseHeadersText;
  }

  /**
   * @param {string} x
   */
  set responseHeadersText(x) {
    this._responseHeadersText = x;

    this.dispatchEventToListeners(Events.ResponseHeadersChanged);
  }

  /**
   * @return {!Array.<!SDK.NetworkRequest.NameValue>}
   */
  get sortedResponseHeaders() {
    if (this._sortedResponseHeaders !== undefined) {
      return this._sortedResponseHeaders;
    }

    this._sortedResponseHeaders = this.responseHeaders.slice();
    this._sortedResponseHeaders.sort(function(a, b) {
      return a.name.toLowerCase().compareTo(b.name.toLowerCase());
    });
    return this._sortedResponseHeaders;
  }

  /**
   * @param {string} headerName
   * @return {string|undefined}
   */
  responseHeaderValue(headerName) {
    if (headerName in this._responseHeaderValues) {
      return this._responseHeaderValues[headerName];
    }
    this._responseHeaderValues[headerName] = this._computeHeaderValue(this.responseHeaders, headerName);
    return this._responseHeaderValues[headerName];
  }

  /**
   * @return {!Array.<!SDK.Cookie>}
   */
  get responseCookies() {
    if (!this._responseCookies) {
      this._responseCookies = SDK.CookieParser.parseSetCookie(this.responseHeaderValue('Set-Cookie'));
    }
    return this._responseCookies;
  }

  /**
   * @return {string|undefined}
   */
  responseLastModified() {
    return this.responseHeaderValue('last-modified');
  }

  /**
   * @return {?Array.<!SDK.ServerTiming>}
   */
  get serverTimings() {
    if (typeof this._serverTimings === 'undefined') {
      this._serverTimings = SDK.ServerTiming.parseHeaders(this.responseHeaders);
    }
    return this._serverTimings;
  }

  /**
   * @return {?string}
   */
  queryString() {
    if (this._queryString !== undefined) {
      return this._queryString;
    }

    let queryString = null;
    const url = this.url();
    const questionMarkPosition = url.indexOf('?');
    if (questionMarkPosition !== -1) {
      queryString = url.substring(questionMarkPosition + 1);
      const hashSignPosition = queryString.indexOf('#');
      if (hashSignPosition !== -1) {
        queryString = queryString.substring(0, hashSignPosition);
      }
    }
    this._queryString = queryString;
    return this._queryString;
  }

  /**
   * @return {?Array.<!SDK.NetworkRequest.NameValue>}
   */
  get queryParameters() {
    if (this._parsedQueryParameters) {
      return this._parsedQueryParameters;
    }
    const queryString = this.queryString();
    if (!queryString) {
      return null;
    }
    this._parsedQueryParameters = this._parseParameters(queryString);
    return this._parsedQueryParameters;
  }

  /**
   * @return {!Promise<?Array<!SDK.NetworkRequest.NameValue>>}
   */
  async _parseFormParameters() {
    const requestContentType = this.requestContentType();

    if (!requestContentType) {
      return null;
    }

    // Handling application/x-www-form-urlencoded request bodies.
    if (requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i)) {
      const formData = await this.requestFormData();
      if (!formData) {
        return null;
      }

      return this._parseParameters(formData);
    }

    // Handling multipart/form-data request bodies.
    const multipartDetails = requestContentType.match(/^multipart\/form-data\s*;\s*boundary\s*=\s*(\S+)\s*$/);

    if (!multipartDetails) {
      return null;
    }

    const boundary = multipartDetails[1];
    if (!boundary) {
      return null;
    }

    const formData = await this.requestFormData();
    if (!formData) {
      return null;
    }

    return this._parseMultipartFormDataParameters(formData, boundary);
  }

  /**
   * @return {!Promise<?Array<!SDK.NetworkRequest.NameValue>>}
   */
  formParameters() {
    if (!this._formParametersPromise) {
      this._formParametersPromise = this._parseFormParameters();
    }
    return this._formParametersPromise;
  }

  /**
   * @return {string}
   */
  responseHttpVersion() {
    const headersText = this._responseHeadersText;
    if (!headersText) {
      const version = this.responseHeaderValue('version') || this.responseHeaderValue(':version');
      if (version) {
        return version;
      }
      return this._filteredProtocolName();
    }
    const firstLine = headersText.split(/\r\n/)[0];
    const match = firstLine.match(/^(HTTP\/\d+\.\d+)/);
    return match ? match[1] : 'HTTP/0.9';
  }

  /**
   * @param {string} queryString
   * @return {!Array.<!SDK.NetworkRequest.NameValue>}
   */
  _parseParameters(queryString) {
    function parseNameValue(pair) {
      const position = pair.indexOf('=');
      if (position === -1) {
        return {name: pair, value: ''};
      } else {
        return {name: pair.substring(0, position), value: pair.substring(position + 1)};
      }
    }
    return queryString.split('&').map(parseNameValue);
  }

  /**
   * Parses multipart/form-data; boundary=boundaryString request bodies -
   * --boundaryString
   * Content-Disposition: form-data; name="field-name"; filename="r.gif"
   * Content-Type: application/octet-stream
   *
   * optionalValue
   * --boundaryString
   * Content-Disposition: form-data; name="field-name-2"
   *
   * optionalValue2
   * --boundaryString--
   *
   * @param {string} data
   * @param {string} boundary
   * @return {!Array.<!SDK.NetworkRequest.NameValue>}
   */
  _parseMultipartFormDataParameters(data, boundary) {
    const sanitizedBoundary = boundary.escapeForRegExp();
    const keyValuePattern = new RegExp(
        // Header with an optional file name.
        '^\\r\\ncontent-disposition\\s*:\\s*form-data\\s*;\\s*name="([^"]*)"(?:\\s*;\\s*filename="([^"]*)")?' +
            // Optional secondary header with the content type.
            '(?:\\r\\ncontent-type\\s*:\\s*([^\\r\\n]*))?' +
            // Padding.
            '\\r\\n\\r\\n' +
            // Value
            '(.*)' +
            // Padding.
            '\\r\\n$',
        'is');
    const fields = data.split(new RegExp(`--${sanitizedBoundary}(?:--\s*$)?`, 'g'));
    return fields.reduce(parseMultipartField, []);

    /**
     * @param {!Array.<!SDK.NetworkRequest.NameValue>} result
     * @param {string} field
     * @return {!Array.<!SDK.NetworkRequest.NameValue>}
     */
    function parseMultipartField(result, field) {
      const [match, name, filename, contentType, value] = field.match(keyValuePattern) || [];

      if (!match) {
        return result;
      }

      const processedValue = (filename || contentType) ? ls`(binary)` : value;
      result.push({name, value: processedValue});

      return result;
    }
  }

  /**
   * @param {!Array.<!SDK.NetworkRequest.NameValue>} headers
   * @param {string} headerName
   * @return {string|undefined}
   */
  _computeHeaderValue(headers, headerName) {
    headerName = headerName.toLowerCase();

    const values = [];
    for (let i = 0; i < headers.length; ++i) {
      if (headers[i].name.toLowerCase() === headerName) {
        values.push(headers[i].value);
      }
    }
    if (!values.length) {
      return undefined;
    }
    // Set-Cookie values should be separated by '\n', not comma, otherwise cookies could not be parsed.
    if (headerName === 'set-cookie') {
      return values.join('\n');
    }
    return values.join(', ');
  }

  /**
   * @return {!Promise<!SDK.NetworkRequest.ContentData>}
   */
  contentData() {
    if (this._contentData) {
      return this._contentData;
    }
    if (this._contentDataProvider) {
      this._contentData = this._contentDataProvider();
    } else {
      this._contentData = SDK.NetworkManager.requestContentData(this);
    }
    return this._contentData;
  }

  /**
   * @param {function():!Promise<!SDK.NetworkRequest.ContentData>} dataProvider
   */
  setContentDataProvider(dataProvider) {
    console.assert(!this._contentData, 'contentData can only be set once.');
    this._contentDataProvider = dataProvider;
  }

  /**
   * @override
   * @return {string}
   */
  contentURL() {
    return this._url;
  }

  /**
   * @override
   * @return {!Common.ResourceType}
   */
  contentType() {
    return this._resourceType;
  }

  /**
   * @override
   * @return {!Promise<boolean>}
   */
  async contentEncoded() {
    return (await this.contentData()).encoded;
  }

  /**
   * @override
   * @return {!Promise<!Common.DeferredContent>}
   */
  async requestContent() {
    const {content, error, encoded} = await this.contentData();
    return /** @type{!Common.DeferredContent} */ ({
      content,
      error,
      isEncoded: encoded,
    });
  }

  /**
   * @override
   * @param {string} query
   * @param {boolean} caseSensitive
   * @param {boolean} isRegex
   * @return {!Promise<!Array<!Common.ContentProvider.SearchMatch>>}
   */
  async searchInContent(query, caseSensitive, isRegex) {
    if (!this._contentDataProvider) {
      return SDK.NetworkManager.searchInRequest(this, query, caseSensitive, isRegex);
    }

    const contentData = await this.contentData();
    let content = contentData.content;
    if (!content) {
      return [];
    }
    if (contentData.encoded) {
      content = window.atob(content);
    }
    return Common.ContentProvider.performSearchInContent(content, query, caseSensitive, isRegex);
  }

  /**
   * @return {boolean}
   */
  isHttpFamily() {
    return !!this.url().match(/^https?:/i);
  }

  /**
   * @return {string|undefined}
   */
  requestContentType() {
    return this.requestHeaderValue('Content-Type');
  }

  /**
   * @return {boolean}
   */
  hasErrorStatusCode() {
    return this.statusCode >= 400;
  }

  /**
   * @param {!Protocol.Network.ResourcePriority} priority
   */
  setInitialPriority(priority) {
    this._initialPriority = priority;
  }

  /**
   * @return {?Protocol.Network.ResourcePriority}
   */
  initialPriority() {
    return this._initialPriority;
  }

  /**
   * @param {!Protocol.Network.ResourcePriority} priority
   */
  setPriority(priority) {
    this._currentPriority = priority;
  }

  /**
   * @return {?Protocol.Network.ResourcePriority}
   */
  priority() {
    return this._currentPriority || this._initialPriority || null;
  }

  /**
   * @param {!Protocol.Network.SignedExchangeInfo} info
   */
  setSignedExchangeInfo(info) {
    this._signedExchangeInfo = info;
  }

  /**
   * @return {?Protocol.Network.SignedExchangeInfo}
   */
  signedExchangeInfo() {
    return this._signedExchangeInfo;
  }

  /**
   * @param {!Element} image
   */
  async populateImageSource(image) {
    const {content, encoded} = await this.contentData();
    let imageSrc = Common.ContentProvider.contentAsDataURL(content, this._mimeType, encoded);
    if (imageSrc === null && !this._failed) {
      const cacheControl = this.responseHeaderValue('cache-control') || '';
      if (!cacheControl.includes('no-cache')) {
        imageSrc = this._url;
      }
    }
    if (imageSrc !== null) {
      image.src = imageSrc;
    }
  }

  /**
   * @return {?Protocol.Network.Initiator}
   */
  initiator() {
    return this._initiator;
  }

  /**
   * @return {!Array.<!SDK.NetworkRequest.WebSocketFrame>}
   */
  frames() {
    return this._frames;
  }

  /**
   * @param {string} errorMessage
   * @param {number} time
   */
  addProtocolFrameError(errorMessage, time) {
    this.addFrame(
        {type: WebSocketFrameType.Error, text: errorMessage, time: this.pseudoWallTime(time), opCode: -1, mask: false});
  }

  /**
   * @param {!Protocol.Network.WebSocketFrame} response
   * @param {number} time
   * @param {boolean} sent
   */
  addProtocolFrame(response, time, sent) {
    const type = sent ? WebSocketFrameType.Send : WebSocketFrameType.Receive;
    this.addFrame({
      type: type,
      text: response.payloadData,
      time: this.pseudoWallTime(time),
      opCode: response.opcode,
      mask: response.mask
    });
  }

  /**
   * @param {!SDK.NetworkRequest.WebSocketFrame} frame
   */
  addFrame(frame) {
    this._frames.push(frame);
    this.dispatchEventToListeners(Events.WebsocketFrameAdded, frame);
  }

  /**
   * @return {!Array.<!SDK.NetworkRequest.EventSourceMessage>}
   */
  eventSourceMessages() {
    return this._eventSourceMessages;
  }

  /**
   * @param {number} time
   * @param {string} eventName
   * @param {string} eventId
   * @param {string} data
   */
  addEventSourceMessage(time, eventName, eventId, data) {
    const message = {time: this.pseudoWallTime(time), eventName: eventName, eventId: eventId, data: data};
    this._eventSourceMessages.push(message);
    this.dispatchEventToListeners(Events.EventSourceMessageAdded, message);
  }

  /**
   * @param {number} redirectCount
   */
  markAsRedirect(redirectCount) {
    this._requestId = `${this._backendRequestId}:redirected.${redirectCount}`;
  }

  /**
   * @param {string} requestId
   */
  setRequestIdForTest(requestId) {
    this._backendRequestId = requestId;
    this._requestId = requestId;
  }

  /**
   * @return {?string}
   */
  charset() {
    const contentTypeHeader = this.responseHeaderValue('content-type');
    if (!contentTypeHeader) {
      return null;
    }

    const responseCharsets = contentTypeHeader.replace(/ /g, '')
                                 .split(';')
                                 .filter(parameter => parameter.toLowerCase().startsWith('charset='))
                                 .map(parameter => parameter.slice('charset='.length));
    if (responseCharsets.length) {
      return responseCharsets[0];
    }

    return null;
  }

  /**
   * @param {!SDK.NetworkRequest.ExtraRequestInfo} extraRequestInfo
   */
  addExtraRequestInfo(extraRequestInfo) {
    this._blockedRequestCookies = extraRequestInfo.blockedRequestCookies;
    this.setRequestHeaders(extraRequestInfo.requestHeaders);
    this._hasExtraRequestInfo = true;
    this.setRequestHeadersText('');  // Mark request headers as non-provisional
  }

  /**
   * @return {boolean}
   */
  hasExtraRequestInfo() {
    return this._hasExtraRequestInfo;
  }

  /**
   * @return {!Array<!SDK.NetworkRequest.BlockedCookieWithReason>}
   */
  blockedRequestCookies() {
    return this._blockedRequestCookies;
  }

  /**
   * @param {!SDK.NetworkRequest.ExtraResponseInfo} extraResponseInfo
   */
  addExtraResponseInfo(extraResponseInfo) {
    this._blockedResponseCookies = extraResponseInfo.blockedResponseCookies;
    this.responseHeaders = extraResponseInfo.responseHeaders;

    if (extraResponseInfo.responseHeadersText) {
      this.responseHeadersText = extraResponseInfo.responseHeadersText;

      if (!this.requestHeadersText()) {
        // Generate request headers text from raw headers in extra request info because
        // Network.requestWillBeSentExtraInfo doesn't include headers text.
        let requestHeadersText = `${this.requestMethod} ${this.parsedURL.path}`;
        if (this.parsedURL.queryParams) {
          requestHeadersText += `?${this.parsedURL.queryParams}`;
        }
        requestHeadersText += ` HTTP/1.1\r\n`;

        for (const {name, value} of this.requestHeaders()) {
          requestHeadersText += `${name}: ${value}\r\n`;
        }
        this.setRequestHeadersText(requestHeadersText);
      }
    }

    this._hasExtraResponseInfo = true;
  }

  /**
   * @return {boolean}
   */
  hasExtraResponseInfo() {
    return this._hasExtraResponseInfo;
  }

  /**
   * @return {!Array<!SDK.NetworkRequest.BlockedSetCookieWithReason>}
   */
  blockedResponseCookies() {
    return this._blockedResponseCookies;
  }
}

/** @enum {symbol} */
export const Events = {
  FinishedLoading: Symbol('FinishedLoading'),
  TimingChanged: Symbol('TimingChanged'),
  RemoteAddressChanged: Symbol('RemoteAddressChanged'),
  RequestHeadersChanged: Symbol('RequestHeadersChanged'),
  ResponseHeadersChanged: Symbol('ResponseHeadersChanged'),
  WebsocketFrameAdded: Symbol('WebsocketFrameAdded'),
  EventSourceMessageAdded: Symbol('EventSourceMessageAdded')
};

/** @enum {string} */
export const InitiatorType = {
  Other: 'other',
  Parser: 'parser',
  Redirect: 'redirect',
  Script: 'script',
  Preload: 'preload',
  SignedExchange: 'signedExchange'
};

/** @enum {string} */
export const WebSocketFrameType = {
  Send: 'send',
  Receive: 'receive',
  Error: 'error'
};

/**
 * @param {!Protocol.Network.CookieBlockedReason} blockedReason
 * @return {string}
 */
export const cookieBlockedReasonToUiString = function(blockedReason) {
  switch (blockedReason) {
    case Protocol.Network.CookieBlockedReason.SecureOnly:
      return ls`This cookie had the "Secure" attribute and the connection was not secure.`;
    case Protocol.Network.CookieBlockedReason.NotOnPath:
      return ls`This cookie's path was not within the request url's path.`;
    case Protocol.Network.CookieBlockedReason.DomainMismatch:
      return ls
      `This cookie's domain is not configured to match the request url's domain, even though they share a common TLD+1 (TLD+1 of foo.bar.example.com is example.com).`;
    case Protocol.Network.CookieBlockedReason.SameSiteStrict:
      return ls
      `This cookie had the "SameSite=Strict" attribute and the request was made on on a different site. This includes navigation requests initiated by other sites.`;
    case Protocol.Network.CookieBlockedReason.SameSiteLax:
      return ls
      `This cookie had the "SameSite=Lax" attribute and the request was made on a different site. This does not include navigation requests initiated by other sites.`;
    case Protocol.Network.CookieBlockedReason.SameSiteUnspecifiedTreatedAsLax:
      return ls
      `This cookie didn't specify a SameSite attribute when it was stored and was defaulted to "SameSite=Lax" and broke the same rules specified in the SameSiteLax value. The cookie had to have been set with "SameSite=None" to enable third-party usage.`;
    case Protocol.Network.CookieBlockedReason.SameSiteNoneInsecure:
      return ls
      `This cookie had the "SameSite=None" attribute but was not marked "Secure". Cookies without SameSite restrictions must be marked "Secure" and sent over a secure connection.`;
    case Protocol.Network.CookieBlockedReason.UserPreferences:
      return ls`This cookie was not sent due to user preferences.`;
    case Protocol.Network.CookieBlockedReason.UnknownError:
      return ls`An unknown error was encountered when trying to send this cookie.`;
  }
  return '';
};

/**
 * @param {!Protocol.Network.SetCookieBlockedReason} blockedReason
 * @return {string}
 */
export const setCookieBlockedReasonToUiString = function(blockedReason) {
  switch (blockedReason) {
    case Protocol.Network.SetCookieBlockedReason.SecureOnly:
      return ls
      `This set-cookie had the "Secure" attribute but was not received over a secure connection.`;
    case Protocol.Network.SetCookieBlockedReason.SameSiteStrict:
      return ls
      `This set-cookie had the "SameSite=Strict" attribute but came from a cross-origin response. This includes navigation requests intitiated by other origins.`;
    case Protocol.Network.SetCookieBlockedReason.SameSiteLax:
      return ls`This set-cookie had the "SameSite=Lax" attribute but came from a cross-origin response.`;
    case Protocol.Network.SetCookieBlockedReason.SameSiteUnspecifiedTreatedAsLax:
      return ls
      `This set-cookie didn't specify a "SameSite" attribute and was defaulted to "SameSite=Lax" and broke the same rules specified in the SameSiteLax value.`;
    case Protocol.Network.SetCookieBlockedReason.SameSiteNoneInsecure:
      return ls
      `This set-cookie had the "SameSite=None" attribute but did not have the "Secure" attribute, which is required in order to use "SameSite=None".`;
    case Protocol.Network.SetCookieBlockedReason.UserPreferences:
      return ls`This set-cookie was not stored due to user preferences.`;
    case Protocol.Network.SetCookieBlockedReason.SyntaxError:
      return ls`This set-cookie had invalid syntax.`;
    case Protocol.Network.SetCookieBlockedReason.SchemeNotSupported:
      return ls`The scheme of this connection is not allowed to store cookies.`;
    case Protocol.Network.SetCookieBlockedReason.OverwriteSecure:
      return ls
      `This set-cookie was not sent over a secure connection and would have overwritten a cookie with the Secure attribute.`;
    case Protocol.Network.SetCookieBlockedReason.InvalidDomain:
      return ls`This set-cookie's Domain attribute was invalid with regards to the current host url.`;
    case Protocol.Network.SetCookieBlockedReason.InvalidPrefix:
      return ls
      `This set-cookie used the "__Secure-" or "__Host-" prefix in its name and broke the additional rules applied to cookies with these prefixes as defined in https://tools.ietf.org/html/draft-west-cookie-prefixes-05.`;
    case Protocol.Network.SetCookieBlockedReason.UnknownError:
      return ls`An unknown error was encountered when trying to store this cookie.`;
  }
  return '';
};

/**
 * @param {!Protocol.Network.CookieBlockedReason} blockedReason
 * @return {?SDK.Cookie.Attributes}
 */
export const cookieBlockedReasonToAttribute = function(blockedReason) {
  switch (blockedReason) {
    case Protocol.Network.CookieBlockedReason.SecureOnly:
      return SDK.Cookie.Attributes.Secure;
    case Protocol.Network.CookieBlockedReason.NotOnPath:
      return SDK.Cookie.Attributes.Path;
    case Protocol.Network.CookieBlockedReason.DomainMismatch:
      return SDK.Cookie.Attributes.Domain;
    case Protocol.Network.CookieBlockedReason.SameSiteStrict:
    case Protocol.Network.CookieBlockedReason.SameSiteLax:
    case Protocol.Network.CookieBlockedReason.SameSiteUnspecifiedTreatedAsLax:
    case Protocol.Network.CookieBlockedReason.SameSiteNoneInsecure:
      return SDK.Cookie.Attributes.SameSite;
    case Protocol.Network.CookieBlockedReason.UserPreferences:
    case Protocol.Network.CookieBlockedReason.UnknownError:
      return null;
  }
  return null;
};

/**
 * @param {!Protocol.Network.SetCookieBlockedReason} blockedReason
 * @return {?SDK.Cookie.Attributes}
 */
export const setCookieBlockedReasonToAttribute = function(blockedReason) {
  switch (blockedReason) {
    case Protocol.Network.SetCookieBlockedReason.SecureOnly:
    case Protocol.Network.SetCookieBlockedReason.OverwriteSecure:
      return SDK.Cookie.Attributes.Secure;
    case Protocol.Network.SetCookieBlockedReason.SameSiteStrict:
    case Protocol.Network.SetCookieBlockedReason.SameSiteLax:
    case Protocol.Network.SetCookieBlockedReason.SameSiteUnspecifiedTreatedAsLax:
    case Protocol.Network.SetCookieBlockedReason.SameSiteNoneInsecure:
      return SDK.Cookie.Attributes.SameSite;
    case Protocol.Network.SetCookieBlockedReason.InvalidDomain:
      return SDK.Cookie.Attributes.Domain;
    case Protocol.Network.SetCookieBlockedReason.InvalidPrefix:
      return SDK.Cookie.Attributes.Name;
    case Protocol.Network.SetCookieBlockedReason.UserPreferences:
    case Protocol.Network.SetCookieBlockedReason.SyntaxError:
    case Protocol.Network.SetCookieBlockedReason.SchemeNotSupported:
    case Protocol.Network.SetCookieBlockedReason.UnknownError:
      return null;
  }
  return null;
};

/* Legacy exported object */
self.SDK = self.SDK || {};

/* Legacy exported object */
SDK = SDK || {};

/** @constructor */
SDK.NetworkRequest = NetworkRequest;

/** @enum {symbol} */
SDK.NetworkRequest.Events = Events;

/** @enum {string} */
SDK.NetworkRequest.InitiatorType = InitiatorType;

/** @enum {string} */
SDK.NetworkRequest.WebSocketFrameType = WebSocketFrameType;

SDK.NetworkRequest.cookieBlockedReasonToUiString = cookieBlockedReasonToUiString;
SDK.NetworkRequest.setCookieBlockedReasonToUiString = setCookieBlockedReasonToUiString;
SDK.NetworkRequest.cookieBlockedReasonToAttribute = cookieBlockedReasonToAttribute;
SDK.NetworkRequest.setCookieBlockedReasonToAttribute = setCookieBlockedReasonToAttribute;

/** @typedef {!{name: string, value: string}} */
SDK.NetworkRequest.NameValue;

/** @typedef {!{type: WebSocketFrameType, time: number, text: string, opCode: number, mask: boolean}} */
SDK.NetworkRequest.WebSocketFrame;

/** @typedef {!{time: number, eventName: string, eventId: string, data: string}} */
SDK.NetworkRequest.EventSourceMessage;

/** @typedef {!{error: ?string, content: ?string, encoded: boolean}} */
SDK.NetworkRequest.ContentData;

/**
 * @typedef {!{
  *   blockedReasons: !Array<!Protocol.Network.CookieBlockedReason>,
  *   cookie: !SDK.Cookie
  * }}
  */
SDK.NetworkRequest.BlockedCookieWithReason;

/**
  * @typedef {!{
  *   blockedRequestCookies: !Array<!SDK.NetworkRequest.BlockedCookieWithReason>,
  *   requestHeaders: !Array<!SDK.NetworkRequest.NameValue>
  * }}
  */
SDK.NetworkRequest.ExtraRequestInfo;

/**
  * @typedef {!{
  *   blockedReasons: !Array<!Protocol.Network.SetCookieBlockedReason>,
  *   cookieLine: string,
  *   cookie: ?SDK.Cookie
  * }}
  */
SDK.NetworkRequest.BlockedSetCookieWithReason;

/**
  * @typedef {!{
  *   blockedResponseCookies: !Array<!SDK.NetworkRequest.BlockedSetCookieWithReason>,
  *   responseHeaders: !Array<!SDK.NetworkRequest.NameValue>,
  *   responseHeadersText: (string|undefined)
  * }}
  */
SDK.NetworkRequest.ExtraResponseInfo;
