Changeset 116952 in webkit


Ignore:
Timestamp:
May 14, 2012 8:44:05 AM (12 years ago)
Author:
vsevik@chromium.org
Message:

Web Inspector: Request / response headers should be stored in name-value pairs array, not a map on front-end.
https://bugs.webkit.org/show_bug.cgi?id=86357

Reviewed by Pavel Feldman.

Source/WebCore:

Storing headers as name-value pairs array information more accurate and allows
to treat Set-Cookie headers (which become not parseable when joined by comma) correctly.

  • inspector/front-end/AuditRules.js:

(WebInspector.AuditRules.GzipRule.prototype._isCompressed):
(WebInspector.AuditRules.CacheControlRule.prototype.responseHeader):
(WebInspector.AuditRules.CacheControlRule.prototype.hasResponseHeader):
(WebInspector.AuditRules.CacheControlRule.prototype.responseHeaderMatch):

  • inspector/front-end/HAREntry.js:

(WebInspector.HAREntry.prototype._buildRequest):
(WebInspector.HAREntry.prototype._buildResponse):

  • inspector/front-end/NetworkManager.js:

(WebInspector.NetworkDispatcher.prototype._headersMapToHeadersArray):
(WebInspector.NetworkDispatcher.prototype._updateNetworkRequestWithRequest):
(WebInspector.NetworkDispatcher.prototype._updateNetworkRequestWithResponse):
(WebInspector.NetworkDispatcher.prototype.webSocketWillSendHandshakeRequest):
(WebInspector.NetworkDispatcher.prototype.webSocketHandshakeResponseReceived):

  • inspector/front-end/NetworkRequest.js:

(WebInspector.NetworkRequest.prototype.get transferSize):
(WebInspector.NetworkRequest.prototype.get requestHeaders):
(WebInspector.NetworkRequest.prototype.get requestHeadersText):
(WebInspector.NetworkRequest.prototype.get responseHeaders):
(WebInspector.NetworkRequest.prototype.get responseHeadersText):
(WebInspector.NetworkRequest.prototype._headerValue):

  • inspector/front-end/RequestHeadersView.js:

(WebInspector.RequestHeadersView.prototype._refreshRequestHeaders):
(WebInspector.RequestHeadersView.prototype._refreshResponseHeaders):
(WebInspector.RequestHeadersView.prototype._refreshHeaders):

  • platform/chromium/support/WebHTTPLoadInfo.cpp:

(WebKit::addHeader):

LayoutTests:

  • http/tests/inspector/resource-har-conversion.html:
  • http/tests/inspector/resource-har-headers-expected.txt:
  • http/tests/inspector/resource-har-headers.html:
Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r116945 r116952  
     12012-05-14  Vsevolod Vlasov  <vsevik@chromium.org>
     2
     3        Web Inspector: Request / response headers should be stored in name-value pairs array, not a map on front-end.
     4        https://bugs.webkit.org/show_bug.cgi?id=86357
     5
     6        Reviewed by Pavel Feldman.
     7
     8        * http/tests/inspector/resource-har-conversion.html:
     9        * http/tests/inspector/resource-har-headers-expected.txt:
     10        * http/tests/inspector/resource-har-headers.html:
     11
    1122012-05-14  Christophe Dumez  <christophe.dumez@intel.com>
    213
  • trunk/LayoutTests/http/tests/inspector/resource-har-conversion.html

    r113863 r116952  
    3737        function addCookieHeadersToRequest(request)
    3838        {
    39             request.requestHeaders = {
    40                 "Cookie": "a=b; $Path=/path; $Domain=example.com; a1=b1\nc1=d1"
    41             };
     39            request.requestHeaders = [
     40                { name: "Cookie", value: "a=b; $Path=/path; $Domain=example.com; a1=b1\nc1=d1" }
     41            ];
    4242
    43             request.responseHeaders = {
    44                 "Set-Cookie": "x=y; Path=/path; Domain=example.com; Discard; httpOnly; Secure; Version=1\nx1=y1\nz2=y2"
    45             };
     43            request.responseHeaders = [
     44                { name: "Set-Cookie", value: "x=y; Path=/path; Domain=example.com; Discard; httpOnly; Secure; Version=1\nx1=y1\nz2=y2" }
     45            ];
    4646        }
    4747
  • trunk/LayoutTests/http/tests/inspector/resource-har-headers-expected.txt

    r105596 r116952  
    33Resource:{
    44    request : {
    5         headers : {
    6             Request : "request-value"
    7         }
     5        headers : [
     6            {
     7                name : "Request"
     8                value : "request-value"
     9            }
     10        ]
    811        headersText : "GET http://example.com/inspector-test.js HTTP/1.1\r\nRequest: headers-text"
    912        headersSize : 72
    1013    }
    1114    response : {
    12         headers : {
    13             Response : "response-value"
    14         }
     15        headers : [
     16            {
     17                name : "Response"
     18                value : "response-value"
     19            }
     20        ]
    1521        headersText : "HTTP/1.1 200 OK\r\nResponse: headers-text"
    1622        headersSize : 39
  • trunk/LayoutTests/http/tests/inspector/resource-har-headers.html

    r113863 r116952  
    1515    function setRequestValues(request)
    1616    {
    17         request.requestHeaders = {
    18             "Request": "request-value"
    19         };
     17        request.requestHeaders = [
     18            { name: "Request", value: "request-value" }
     19        ];
    2020        request.requestHeadersText = "GET http://example.com/inspector-test.js HTTP/1.1\r\nRequest: headers-text";
    2121
    22         request.responseHeaders = {
    23             "Response": "response-value"
    24         };
     22        request.responseHeaders = [
     23            { name: "Response", value: "response-value" }
     24        ];
    2525        request.responseHeadersText = "HTTP/1.1 200 OK\r\nResponse: headers-text";
    2626
  • trunk/Source/WebCore/ChangeLog

    r116949 r116952  
     12012-05-14  Vsevolod Vlasov  <vsevik@chromium.org>
     2
     3        Web Inspector: Request / response headers should be stored in name-value pairs array, not a map on front-end.
     4        https://bugs.webkit.org/show_bug.cgi?id=86357
     5
     6        Reviewed by Pavel Feldman.
     7
     8        Storing headers as name-value pairs array information more accurate and allows
     9        to treat Set-Cookie headers (which become not parseable when joined by comma) correctly.
     10
     11        * inspector/front-end/AuditRules.js:
     12        (WebInspector.AuditRules.GzipRule.prototype._isCompressed):
     13        (WebInspector.AuditRules.CacheControlRule.prototype.responseHeader):
     14        (WebInspector.AuditRules.CacheControlRule.prototype.hasResponseHeader):
     15        (WebInspector.AuditRules.CacheControlRule.prototype.responseHeaderMatch):
     16        * inspector/front-end/HAREntry.js:
     17        (WebInspector.HAREntry.prototype._buildRequest):
     18        (WebInspector.HAREntry.prototype._buildResponse):
     19        * inspector/front-end/NetworkManager.js:
     20        (WebInspector.NetworkDispatcher.prototype._headersMapToHeadersArray):
     21        (WebInspector.NetworkDispatcher.prototype._updateNetworkRequestWithRequest):
     22        (WebInspector.NetworkDispatcher.prototype._updateNetworkRequestWithResponse):
     23        (WebInspector.NetworkDispatcher.prototype.webSocketWillSendHandshakeRequest):
     24        (WebInspector.NetworkDispatcher.prototype.webSocketHandshakeResponseReceived):
     25        * inspector/front-end/NetworkRequest.js:
     26        (WebInspector.NetworkRequest.prototype.get transferSize):
     27        (WebInspector.NetworkRequest.prototype.get requestHeaders):
     28        (WebInspector.NetworkRequest.prototype.get requestHeadersText):
     29        (WebInspector.NetworkRequest.prototype.get responseHeaders):
     30        (WebInspector.NetworkRequest.prototype.get responseHeadersText):
     31        (WebInspector.NetworkRequest.prototype._headerValue):
     32        * inspector/front-end/RequestHeadersView.js:
     33        (WebInspector.RequestHeadersView.prototype._refreshRequestHeaders):
     34        (WebInspector.RequestHeadersView.prototype._refreshResponseHeaders):
     35        (WebInspector.RequestHeadersView.prototype._refreshHeaders):
     36        * platform/chromium/support/WebHTTPLoadInfo.cpp:
     37        (WebKit::addHeader):
     38
    1392012-05-14  Sriram Neelakandan  <sriram.neelakandan@gmail.com>
    240
  • trunk/Source/WebCore/inspector/front-end/AuditRules.js

    r114880 r116952  
    108108    _isCompressed: function(request)
    109109    {
    110         var encodingHeader = request.responseHeaders["Content-Encoding"];
     110        var encodingHeader = request.responseHeaderValue("Content-Encoding");
    111111        if (!encodingHeader)
    112112            return false;
     
    518518    responseHeader: function(request, header)
    519519    {
    520         return request.responseHeaders[header];
     520        return request.responseHeaderValue(header);
    521521    },
    522522
    523523    hasResponseHeader: function(request, header)
    524524    {
    525         return request.responseHeaders[header] !== undefined;
     525        return request.responseHeaderValue(header) !== undefined;
    526526    },
    527527
     
    544544    responseHeaderMatch: function(request, header, regexp)
    545545    {
    546         return request.responseHeaders[header]
    547             ? request.responseHeaders[header].match(new RegExp(regexp, "im"))
     546        return request.responseHeaderValue(header)
     547            ? request.responseHeaderValue(header).match(new RegExp(regexp, "im"))
    548548            : undefined;
    549549    },
  • trunk/Source/WebCore/inspector/front-end/HAREntry.js

    r113863 r116952  
    7373            url: this._buildRequestURL(this._request.url),
    7474            httpVersion: this._request.requestHttpVersion,
    75             headers: this._buildHeaders(this._request.requestHeaders),
     75            headers: this._request.requestHeaders,
    7676            queryString: this._buildParameters(this._request.queryParameters || []),
    7777            cookies: this._buildCookies(this._request.requestCookies || []),
     
    9494            statusText: this._request.statusText,
    9595            httpVersion: this._request.responseHttpVersion,
    96             headers: this._buildHeaders(this._request.responseHeaders),
     96            headers: this._request.responseHeaders,
    9797            cookies: this._buildCookies(this._request.responseCookies || []),
    9898            content: this._buildContent(),
     
    153153            ssl: ssl
    154154        };
    155     },
    156 
    157     /**
    158      * @return {Object}
    159      */
    160     _buildHeaders: function(headers)
    161     {
    162         var result = [];
    163         for (var name in headers)
    164             result.push({ name: name, value: headers[name] });
    165         return result;
    166155    },
    167156
  • trunk/Source/WebCore/inspector/front-end/NetworkManager.js

    r115984 r116952  
    153153WebInspector.NetworkDispatcher.prototype = {
    154154    /**
     155     * @param {NetworkAgent.Headers} headersMap
     156     * @return {Array.<Object>}
     157     */
     158    _headersMapToHeadersArray: function(headersMap)
     159    {
     160        var result = [];
     161        for (var name in headersMap) {
     162            var values = headersMap[name].split("\n");
     163            for (var i = 0; i < values.length; ++i)
     164                result.push({ name: name, value: values[i] });
     165        }
     166        return result;
     167    },
     168
     169    /**
    155170     * @param {WebInspector.NetworkRequest} networkRequest
    156171     * @param {NetworkAgent.Request} request
     
    159174    {
    160175        networkRequest.requestMethod = request.method;
    161         networkRequest.requestHeaders = request.headers;
     176        networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers);
    162177        networkRequest.requestFormData = request.postData;
    163178    },
     
    177192        networkRequest.statusCode = response.status;
    178193        networkRequest.statusText = response.statusText;
    179         networkRequest.responseHeaders = response.headers;
     194        networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
    180195        if (response.headersText)
    181196            networkRequest.responseHeadersText = response.headersText;
    182197        if (response.requestHeaders)
    183             networkRequest.requestHeaders = response.requestHeaders;
     198            networkRequest.requestHeaders = this._headersMapToHeadersArray(response.requestHeaders);
    184199        if (response.requestHeadersText)
    185200            networkRequest.requestHeadersText = response.requestHeadersText;
     
    427442
    428443        networkRequest.requestMethod = "GET";
    429         networkRequest.requestHeaders = request.headers;
     444        networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers);
    430445        networkRequest.webSocketRequestKey3 = request.requestKey3;
    431446        networkRequest.startTime = time;
     
    447462        networkRequest.statusCode = response.status;
    448463        networkRequest.statusText = response.statusText;
    449         networkRequest.responseHeaders = response.headers;
     464        networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
    450465        networkRequest.webSocketChallengeResponse = response.challengeResponse;
    451466        networkRequest.responseReceivedTime = time;
  • trunk/Source/WebCore/inspector/front-end/NetworkRequest.js

    r115804 r116952  
    241241        // work for chunks with non-trivial encodings. We need a way to
    242242        // get actual transfer size from the network stack.
    243         var bodySize = Number(this.responseHeaders["Content-Length"] || this.resourceSize);
     243        var bodySize = Number(this.responseHeaderValue("Content-Length") || this.resourceSize);
    244244        return this.responseHeadersSize + bodySize;
    245245    },
     
    400400
    401401    /**
    402      * @return {Object}
     402     * @return {Array.<Object>}
    403403     */
    404404    get requestHeaders()
    405405    {
    406         return this._requestHeaders || {};
     406        return this._requestHeaders || [];
    407407    },
    408408
     
    423423        if (this._requestHeadersText === undefined) {
    424424            this._requestHeadersText = this.requestMethod + " " + this.url + " HTTP/1.1\r\n";
    425             for (var key in this.requestHeaders)
    426                 this._requestHeadersText += key + ": " + this.requestHeaders[key] + "\r\n";
     425            for (var i = 0; i < this.requestHeaders; ++i)
     426                this._requestHeadersText += this.requestHeaders[i].name + ": " + this.requestHeaders[i].value + "\r\n";
    427427        }
    428428        return this._requestHeadersText;
     
    453453
    454454        this._sortedRequestHeaders = [];
    455         for (var key in this.requestHeaders)
    456             this._sortedRequestHeaders.push({header: key, value: this.requestHeaders[key]});
    457         this._sortedRequestHeaders.sort(function(a,b) { return a.header.localeCompare(b.header) });
    458 
     455        this._sortedRequestHeaders = this.requestHeaders.slice();
     456        this._sortedRequestHeaders.sort(function(a,b) { return a.name.toLowerCase().localeCompare(b.name.toLowerCase()) });
    459457        return this._sortedRequestHeaders;
    460458    },
     
    504502
    505503    /**
    506      * @return {Object}
     504     * @return {Array.<Object>}
    507505     */
    508506    get responseHeaders()
    509507    {
    510         return this._responseHeaders || {};
     508        return this._responseHeaders || [];
    511509    },
    512510
     
    527525        if (this._responseHeadersText === undefined) {
    528526            this._responseHeadersText = "HTTP/1.1 " + this.statusCode + " " + this.statusText + "\r\n";
    529             for (var key in this.responseHeaders)
    530                 this._responseHeadersText += key + ": " + this.responseHeaders[key] + "\r\n";
     527            for (var i = 0; i < this.requestHeaders; ++i)
     528                this._responseHeadersText += this.responseHeaders[i].name + ": " + this.responseHeaders[i].value + "\r\n";
    531529        }
    532530        return this._responseHeadersText;
     
    555553        if (this._sortedResponseHeaders !== undefined)
    556554            return this._sortedResponseHeaders;
    557 
     555       
    558556        this._sortedResponseHeaders = [];
    559         for (var key in this.responseHeaders)
    560             this._sortedResponseHeaders.push({header: key, value: this.responseHeaders[key]});
    561         this._sortedResponseHeaders.sort(function(a,b) { return a.header.localeCompare(b.header) });
    562 
     557        this._sortedResponseHeaders = this.responseHeaders.slice();
     558        this._sortedResponseHeaders.sort(function(a,b) { return a.name.toLowerCase().localeCompare(b.name.toLowerCase()) });
    563559        return this._sortedResponseHeaders;
    564560    },
     
    652648    {
    653649        headerName = headerName.toLowerCase();
    654         for (var header in headers) {
    655             if (header.toLowerCase() === headerName)
    656                 return headers[header];
    657         }
     650       
     651        var values = [];
     652        for (var i = 0; i < headers.length; ++i) {
     653            if (headers[i].name.toLowerCase() === headerName)
     654                values.push(headers[i].value);
     655        }
     656        // Set-Cookie values should be separated by '\n', not comma, otherwise cookies could not be parsed.
     657        if (headerName === "set-cookie")
     658            return values.join("\n");
     659        return values.join(", ");
    658660    },
    659661
  • trunk/Source/WebCore/inspector/front-end/RequestHeadersView.js

    r114117 r116952  
    270270        var additionalRow = null;
    271271        if (typeof this._request.webSocketRequestKey3 !== "undefined")
    272             additionalRow = {header: "(Key3)", value: this._request.webSocketRequestKey3};
     272            additionalRow = {name: "(Key3)", value: this._request.webSocketRequestKey3};
    273273        if (this._showRequestHeadersText)
    274274            this._refreshHeadersText(WebInspector.UIString("Request Headers"), this._request.sortedRequestHeaders, this._request.requestHeadersText, this._requestHeadersTreeElement);
     
    289289        var additionalRow = null;
    290290        if (typeof this._request.webSocketChallengeResponse !== "undefined")
    291             additionalRow = {header: "(Challenge Response)", value: this._request.webSocketChallengeResponse};
     291            additionalRow = {name: "(Challenge Response)", value: this._request.webSocketChallengeResponse};
    292292        if (this._showResponseHeadersText)
    293293            this._refreshHeadersText(WebInspector.UIString("Response Headers"), this._request.sortedResponseHeaders, this._request.responseHeadersText, this._responseHeadersTreeElement);
     
    355355        for (var i = 0; i < length; ++i) {
    356356            var headerTreeElement = new TreeElement(null, null, false);
    357             headerTreeElement.title = this._formatHeader(headers[i].header, headers[i].value);
     357            headerTreeElement.title = this._formatHeader(headers[i].name, headers[i].value);
    358358            headerTreeElement.selectable = false;
    359359            headersTreeElement.appendChild(headerTreeElement);
     
    362362        if (additionalRow) {
    363363            var headerTreeElement = new TreeElement(null, null, false);
    364             headerTreeElement.title = this._formatHeader(additionalRow.header, additionalRow.value);
     364            headerTreeElement.title = this._formatHeader(additionalRow.name, additionalRow.value);
    365365            headerTreeElement.selectable = false;
    366366            headersTreeElement.appendChild(headerTreeElement);
  • trunk/Source/WebCore/platform/chromium/support/WebHTTPLoadInfo.cpp

    r112754 r116952  
    105105{
    106106    HTTPHeaderMap::AddResult result = map->add(name, value);
     107    // It is important that values are separated by '\n', not comma, otherwise Set-Cookie header is not parseable.
    107108    if (!result.isNewEntry)
    108         result.iterator->second += ", " + String(value);
     109        result.iterator->second += "\n" + String(value);
    109110}
    110111
Note: See TracChangeset for help on using the changeset viewer.