Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2016 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """The request data track. | 5 """The request data track. |
| 6 | 6 |
| 7 When executed, parses a JSON dump of DevTools messages. | 7 When executed, parses a JSON dump of DevTools messages. |
| 8 """ | 8 """ |
| 9 | 9 |
| 10 import bisect | 10 import bisect |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 172 for (k, v) in data_dict.items(): | 172 for (k, v) in data_dict.items(): |
| 173 setattr(result, k, v) | 173 setattr(result, k, v) |
| 174 if not result.response_headers: | 174 if not result.response_headers: |
| 175 result.response_headers = {} | 175 result.response_headers = {} |
| 176 if result.timing: | 176 if result.timing: |
| 177 result.timing = Timing(*result.timing) | 177 result.timing = Timing(*result.timing) |
| 178 else: | 178 else: |
| 179 result.timing = TimingFromDict({'requestTime': result.timestamp}) | 179 result.timing = TimingFromDict({'requestTime': result.timestamp}) |
| 180 return result | 180 return result |
| 181 | 181 |
| 182 """Gets the value of a HTTP response header. | |
|
Benoit L
2016/02/18 11:01:27
docstrings go below the function name, not above.
| |
| 183 | |
| 184 Does a case-insensitive search for the header name in the HTTP response | |
| 185 headers, in order to support servers that use a wrong capitalization. | |
| 186 """ | |
| 187 def GetHTTPResponseHeader(self, header_name): | |
| 188 small_caps_name = header_name.lower() | |
|
Benoit L
2016/02/18 11:01:27
nit: lower_case_name?
| |
| 189 result = None | |
| 190 for name, value in self.response_headers.iteritems(): | |
| 191 if name.lower() == small_caps_name: | |
| 192 result = value | |
| 193 break | |
| 194 return result | |
| 195 | |
| 182 def GetContentType(self): | 196 def GetContentType(self): |
| 183 """Returns the content type, or None.""" | 197 """Returns the content type, or None.""" |
| 198 # Check for redirects. Use the "Location" header, because the HTTP status is | |
| 199 # not reliable. | |
| 200 if self.GetHTTPResponseHeader('Location') is not None: | |
| 201 return 'redirect' | |
| 202 | |
| 203 # Check if the response is empty. | |
| 204 if (self.GetHTTPResponseHeader('Content-Length') == '0' or | |
| 205 self.status == 204): | |
| 206 return 'ping' | |
| 207 | |
| 184 if self.mime_type: | 208 if self.mime_type: |
| 185 return self.mime_type | 209 return self.mime_type |
| 186 | 210 |
| 187 # Case-insensitive search because servers sometimes use a wrong | 211 content_type = self.GetHTTPResponseHeader('Content-Type') |
| 188 # capitalization. | |
| 189 content_type = None | |
| 190 for header, value in self.response_headers.iteritems(): | |
| 191 if header.lower() == 'content-type': | |
| 192 content_type = value | |
| 193 break | |
| 194 | |
| 195 if not content_type or ';' not in content_type: | 212 if not content_type or ';' not in content_type: |
| 196 return content_type | 213 return content_type |
| 197 else: | 214 else: |
| 198 return content_type[:content_type.index(';')] | 215 return content_type[:content_type.index(';')] |
| 199 | 216 |
| 200 def IsDataRequest(self): | 217 def IsDataRequest(self): |
| 201 return self.protocol == 'data' | 218 return self.protocol == 'data' |
| 202 | 219 |
| 203 def MaxAge(self): | 220 def MaxAge(self): |
| 204 """Returns the max-age of a resource, or -1.""" | 221 """Returns the max-age of a resource, or -1.""" |
| 205 # TODO(lizeb): Handle the "Expires" header as well. | 222 # TODO(lizeb): Handle the "Expires" header as well. |
| 206 cache_control = {} | 223 cache_control = {} |
| 207 if not self.response_headers: | 224 if not self.response_headers: |
| 208 return -1 | 225 return -1 |
| 209 | 226 |
| 210 # Case-insensitive search because servers sometimes use a wrong | 227 cache_control_str = self.GetHTTPResponseHeader('Cache-Control') |
| 211 # capitalization. | |
| 212 cache_control_str = None | |
| 213 for header, value in self.response_headers.iteritems(): | |
| 214 if header.lower() == 'cache-control': | |
| 215 cache_control_str = value | |
| 216 break | |
| 217 | |
| 218 if cache_control_str is not None: | 228 if cache_control_str is not None: |
| 219 directives = [s.strip() for s in cache_control_str.split(',')] | 229 directives = [s.strip() for s in cache_control_str.split(',')] |
| 220 for directive in directives: | 230 for directive in directives: |
| 221 parts = [s.strip() for s in directive.split('=')] | 231 parts = [s.strip() for s in directive.split('=')] |
| 222 if len(parts) == 1: | 232 if len(parts) == 1: |
| 223 cache_control[parts[0]] = True | 233 cache_control[parts[0]] = True |
| 224 else: | 234 else: |
| 225 cache_control[parts[0]] = parts[1] | 235 cache_control[parts[0]] = parts[1] |
| 226 if (u'no-store' in cache_control | 236 if (u'no-store' in cache_control |
| 227 or u'no-cache' in cache_control | 237 or u'no-cache' in cache_control |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 554 | 564 |
| 555 | 565 |
| 556 if __name__ == '__main__': | 566 if __name__ == '__main__': |
| 557 import json | 567 import json |
| 558 import sys | 568 import sys |
| 559 events = json.load(open(sys.argv[1], 'r')) | 569 events = json.load(open(sys.argv[1], 'r')) |
| 560 request_track = RequestTrack(None) | 570 request_track = RequestTrack(None) |
| 561 for event in events: | 571 for event in events: |
| 562 event_method = event['method'] | 572 event_method = event['method'] |
| 563 request_track.Handle(event_method, event) | 573 request_track.Handle(event_method, event) |
| OLD | NEW |