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 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 self._requests_by_end = sorted(valid_requests, | 688 self._requests_by_end = sorted(valid_requests, |
689 key=lambda r: r.end_msec) | 689 key=lambda r: r.end_msec) |
690 self._request_end_timestamps = [r.end_msec | 690 self._request_end_timestamps = [r.end_msec |
691 for r in self._requests_by_end] | 691 for r in self._requests_by_end] |
692 self._indexed = True | 692 self._indexed = True |
693 | 693 |
694 def _RequestWillBeSent(self, request_id, params): | 694 def _RequestWillBeSent(self, request_id, params): |
695 # Several "requestWillBeSent" events can be dispatched in a row in the case | 695 # Several "requestWillBeSent" events can be dispatched in a row in the case |
696 # of redirects. | 696 # of redirects. |
697 redirect_initiator = None | 697 redirect_initiator = None |
| 698 if request_id in self._completed_requests_by_id: |
| 699 assert request_id not in self._requests_in_flight |
| 700 return |
698 if request_id in self._requests_in_flight: | 701 if request_id in self._requests_in_flight: |
699 redirect_initiator = self._HandleRedirect(request_id, params) | 702 redirect_initiator = self._HandleRedirect(request_id, params) |
700 assert (request_id not in self._requests_in_flight | 703 assert (request_id not in self._requests_in_flight) |
701 and request_id not in self._completed_requests_by_id) | |
702 r = Request() | 704 r = Request() |
703 r.request_id = request_id | 705 r.request_id = request_id |
704 _CopyFromDictToObject( | 706 _CopyFromDictToObject( |
705 params, r, (('frameId', 'frame_id'), ('loaderId', 'loader_id'), | 707 params, r, (('frameId', 'frame_id'), ('loaderId', 'loader_id'), |
706 ('documentURL', 'document_url'), | 708 ('documentURL', 'document_url'), |
707 ('timestamp', 'timestamp'), ('wallTime', 'wall_time'), | 709 ('timestamp', 'timestamp'), ('wallTime', 'wall_time'), |
708 ('initiator', 'initiator'))) | 710 ('initiator', 'initiator'))) |
709 request = params['request'] | 711 request = params['request'] |
710 _CopyFromDictToObject( | 712 _CopyFromDictToObject( |
711 request, r, (('url', 'url'), ('method', 'method'), | 713 request, r, (('url', 'url'), ('method', 'method'), |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
752 return initiator | 754 return initiator |
753 | 755 |
754 def _RequestServedFromCache(self, request_id, _): | 756 def _RequestServedFromCache(self, request_id, _): |
755 if request_id not in self._requests_in_flight: | 757 if request_id not in self._requests_in_flight: |
756 return | 758 return |
757 (request, status) = self._requests_in_flight[request_id] | 759 (request, status) = self._requests_in_flight[request_id] |
758 assert status == RequestTrack._STATUS_SENT | 760 assert status == RequestTrack._STATUS_SENT |
759 request.served_from_cache = True | 761 request.served_from_cache = True |
760 | 762 |
761 def _ResponseReceived(self, request_id, params): | 763 def _ResponseReceived(self, request_id, params): |
| 764 if request_id in self._completed_requests_by_id: |
| 765 assert request_id not in self._requests_in_flight |
| 766 return |
762 assert request_id in self._requests_in_flight | 767 assert request_id in self._requests_in_flight |
763 (r, status) = self._requests_in_flight[request_id] | 768 (r, status) = self._requests_in_flight[request_id] |
764 if status == RequestTrack._STATUS_RESPONSE: | 769 if status == RequestTrack._STATUS_RESPONSE: |
765 # Duplicated messages (apart from the timestamp) are OK. | 770 # Duplicated messages (apart from the timestamp) are OK. |
766 old_params = self._request_id_to_response_received[request_id] | 771 old_params = self._request_id_to_response_received[request_id] |
767 params_copy = copy.deepcopy(params) | 772 params_copy = copy.deepcopy(params) |
768 params_copy['timestamp'] = None | 773 params_copy['timestamp'] = None |
769 old_params['timestamp'] = None | 774 old_params['timestamp'] = None |
770 assert params_copy == old_params | 775 assert params_copy == old_params |
771 self.duplicates_count += 1 | 776 self.duplicates_count += 1 |
772 return | 777 return |
773 assert status == RequestTrack._STATUS_SENT | 778 assert status == RequestTrack._STATUS_SENT |
774 assert r.frame_id == params['frameId'] | 779 assert (r.frame_id == params['frameId'] or |
| 780 params['response']['protocol'] == 'data') |
775 assert r.timestamp <= params['timestamp'] | 781 assert r.timestamp <= params['timestamp'] |
776 if r.resource_type == 'Other': | 782 if r.resource_type == 'Other': |
777 r.resource_type = params.get('type', 'Other') | 783 r.resource_type = params.get('type', 'Other') |
778 else: | 784 else: |
779 assert r.resource_type == params.get('type', 'Other') | 785 assert r.resource_type == params.get('type', 'Other') |
780 response = params['response'] | 786 response = params['response'] |
781 _CopyFromDictToObject( | 787 _CopyFromDictToObject( |
782 response, r, (('status', 'status'), ('mimeType', 'mime_type'), | 788 response, r, (('status', 'status'), ('mimeType', 'mime_type'), |
783 ('fromDiskCache', 'from_disk_cache'), | 789 ('fromDiskCache', 'from_disk_cache'), |
784 ('fromServiceWorker', 'from_service_worker'), | 790 ('fromServiceWorker', 'from_service_worker'), |
(...skipping 24 matching lines...) Expand all Loading... |
809 r.data_chunks.append((offset, params['encodedDataLength'])) | 815 r.data_chunks.append((offset, params['encodedDataLength'])) |
810 self._requests_in_flight[request_id] = (r, RequestTrack._STATUS_DATA) | 816 self._requests_in_flight[request_id] = (r, RequestTrack._STATUS_DATA) |
811 | 817 |
812 def _LoadingFinished(self, request_id, params): | 818 def _LoadingFinished(self, request_id, params): |
813 if request_id not in self._requests_in_flight: | 819 if request_id not in self._requests_in_flight: |
814 return | 820 return |
815 (r, status) = self._requests_in_flight[request_id] | 821 (r, status) = self._requests_in_flight[request_id] |
816 assert (status == RequestTrack._STATUS_RESPONSE | 822 assert (status == RequestTrack._STATUS_RESPONSE |
817 or status == RequestTrack._STATUS_DATA) | 823 or status == RequestTrack._STATUS_DATA) |
818 r.encoded_data_length = params['encodedDataLength'] | 824 r.encoded_data_length = params['encodedDataLength'] |
819 assert (r.encoded_data_length > 0 or r.protocol == 'about' or | 825 assert (r.encoded_data_length > 0 or r.protocol in {'about', 'data'} or |
820 r.from_disk_cache or r.served_from_cache) | 826 r.from_disk_cache or r.served_from_cache) |
821 r.timing.loading_finished = r._TimestampOffsetFromStartMs( | 827 r.timing.loading_finished = r._TimestampOffsetFromStartMs( |
822 params['timestamp']) | 828 params['timestamp']) |
823 self._requests_in_flight[request_id] = (r, RequestTrack._STATUS_FINISHED) | 829 self._requests_in_flight[request_id] = (r, RequestTrack._STATUS_FINISHED) |
824 self._FinalizeRequest(request_id) | 830 self._FinalizeRequest(request_id) |
825 | 831 |
826 def _LoadingFailed(self, request_id, params): | 832 def _LoadingFailed(self, request_id, params): |
827 if request_id not in self._requests_in_flight: | 833 if request_id not in self._requests_in_flight: |
828 logging.warning('An unknown request failed: %s' % request_id) | 834 logging.warning('An unknown request failed: %s' % request_id) |
829 return | 835 return |
830 (r, _) = self._requests_in_flight[request_id] | 836 (r, _) = self._requests_in_flight[request_id] |
831 r.failed = True | 837 r.failed = True |
832 r.error_text = params['errorText'] | 838 r.error_text = params['errorText'] |
833 self._requests_in_flight[request_id] = (r, RequestTrack._STATUS_FINISHED) | 839 self._requests_in_flight[request_id] = (r, RequestTrack._STATUS_FINISHED) |
834 self._FinalizeRequest(request_id) | 840 self._FinalizeRequest(request_id) |
835 | 841 |
836 def _FinalizeRequest(self, request_id): | 842 def _FinalizeRequest(self, request_id): |
837 if request_id not in self._requests_in_flight: | |
838 return | |
839 (request, status) = self._requests_in_flight[request_id] | 843 (request, status) = self._requests_in_flight[request_id] |
840 assert status == RequestTrack._STATUS_FINISHED | 844 assert status == RequestTrack._STATUS_FINISHED |
841 del self._requests_in_flight[request_id] | 845 del self._requests_in_flight[request_id] |
842 self._completed_requests_by_id[request_id] = request | 846 self._completed_requests_by_id[request_id] = request |
843 self._requests.append(request) | 847 self._requests.append(request) |
844 | 848 |
845 def __eq__(self, o): | 849 def __eq__(self, o): |
846 return self._requests == o._requests | 850 return self._requests == o._requests |
847 | 851 |
848 | 852 |
(...skipping 13 matching lines...) Expand all Loading... |
862 | 866 |
863 | 867 |
864 if __name__ == '__main__': | 868 if __name__ == '__main__': |
865 import json | 869 import json |
866 import sys | 870 import sys |
867 events = json.load(open(sys.argv[1], 'r')) | 871 events = json.load(open(sys.argv[1], 'r')) |
868 request_track = RequestTrack(None) | 872 request_track = RequestTrack(None) |
869 for event in events: | 873 for event in events: |
870 event_method = event['method'] | 874 event_method = event['method'] |
871 request_track.Handle(event_method, event) | 875 request_track.Handle(event_method, event) |
OLD | NEW |