Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: Tools/Scripts/webkitpy/thirdparty/webpagereplay/customhandlers.py

Issue 18418010: Check in the thirdparty libs needed for webkitpy. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright 2010 Google Inc. All Rights Reserved.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 """Handle special HTTP requests.
17
18 /web-page-replay-generate-[RESPONSE_CODE]
19 - Return the given RESPONSE_CODE.
20 /web-page-replay-post-image-[FILENAME]
21 - Save the posted image to local disk.
22 /web-page-replay-command-[record|replay|status]
23 - Optional. Enable by calling custom_handlers.add_server_manager_handler(...).
24 - Change the server mode to either record or replay.
25 + When switching to record, the http_archive is cleared.
26 + When switching to replay, the http_archive is maintained.
27 """
28
29 import base64
30 import httparchive
31 import httplib
32 import json
33 import logging
34 import os
35
36 COMMON_URL_PREFIX = '/web-page-replay-'
37 COMMAND_URL_PREFIX = COMMON_URL_PREFIX + 'command-'
38 GENERATOR_URL_PREFIX = COMMON_URL_PREFIX + 'generate-'
39 POST_IMAGE_URL_PREFIX = COMMON_URL_PREFIX + 'post-image-'
40 IMAGE_DATA_PREFIX = 'data:image/png;base64,'
41
42
43 def SimpleResponse(status):
44 """Return a ArchivedHttpResponse with |status| code and a simple text body."""
45 return httparchive.create_response(status)
46
47
48 def JsonResponse(data):
49 """Return a ArchivedHttpResponse with |data| encoded as json in the body."""
50 status = 200
51 reason = 'OK'
52 headers = [('content-type', 'application/json')]
53 body = json.dumps(data)
54 return httparchive.create_response(status, reason, headers, body)
55
56
57 class CustomHandlers(object):
58
59 def __init__(self, screenshot_dir=None):
60 """Initialize CustomHandlers.
61
62 Args:
63 screenshot_dir: a path to which screenshots are saved.
64 """
65 self.handlers = [
66 (GENERATOR_URL_PREFIX, self.get_generator_url_response_code)]
67 if screenshot_dir:
68 if not os.path.exists(screenshot_dir):
69 try:
70 os.makedirs(screenshot_dir)
71 except IOError:
72 logging.error('Unable to create screenshot dir: %s', screenshot_dir)
73 screenshot_dir = None
74 if screenshot_dir:
75 self.screenshot_dir = screenshot_dir
76 self.handlers.append(
77 (POST_IMAGE_URL_PREFIX, self.handle_possible_post_image))
78
79 def handle(self, request):
80 """Dispatches requests to matching handlers.
81
82 Args:
83 request: an http request
84 Returns:
85 ArchivedHttpResponse or None.
86 """
87 for prefix, handler in self.handlers:
88 if request.path.startswith(prefix):
89 return handler(request, request.path[len(prefix):])
90 return None
91
92 def get_generator_url_response_code(self, request, url_suffix):
93 """Parse special generator URLs for the embedded response code.
94
95 Clients like perftracker can use URLs of this form to request
96 a response with a particular response code.
97
98 Args:
99 request: an ArchivedHttpRequest instance
100 url_suffix: string that is after the handler prefix (e.g. 304)
101 Returns:
102 On a match, an ArchivedHttpResponse.
103 Otherwise, None.
104 """
105 try:
106 response_code = int(url_suffix)
107 return SimpleResponse(response_code)
108 except ValueError:
109 return None
110
111 def handle_possible_post_image(self, request, url_suffix):
112 """If sent, saves embedded image to local directory.
113
114 Expects a special url containing the filename. If sent, saves the base64
115 encoded request body as a PNG image locally. This feature is enabled by
116 passing in screenshot_dir to the initializer for this class.
117
118 Args:
119 request: an ArchivedHttpRequest instance
120 url_suffix: string that is after the handler prefix (e.g. 'foo.png')
121 Returns:
122 On a match, an ArchivedHttpResponse.
123 Otherwise, None.
124 """
125 basename = url_suffix
126 if not basename:
127 return None
128
129 data = request.request_body
130 if not data.startswith(IMAGE_DATA_PREFIX):
131 logging.error('Unexpected image format for: %s', basename)
132 return SimpleResponse(400)
133
134 data = data[len(IMAGE_DATA_PREFIX):]
135 png = base64.b64decode(data)
136 filename = os.path.join(self.screenshot_dir,
137 '%s-%s.png' % (request.host, basename))
138 if not os.access(self.screenshot_dir, os.W_OK):
139 logging.error('Unable to write to: %s', filename)
140 return SimpleResponse(400)
141
142 with file(filename, 'w') as f:
143 f.write(png)
144 return SimpleResponse(200)
145
146 def add_server_manager_handler(self, server_manager):
147 """Add the ability to change the server mode (e.g. to record mode).
148 Args:
149 server_manager: a servermanager.ServerManager instance.
150 """
151 self.server_manager = server_manager
152 self.handlers.append(
153 (COMMAND_URL_PREFIX, self.handle_server_manager_command))
154
155 def handle_server_manager_command(self, request, url_suffix):
156 """Parse special URLs for the embedded server manager command.
157
158 Clients like webpagetest.org can use URLs of this form to change
159 the replay server from record mode to replay mode.
160
161 This handler is not in the default list of handlers. Call
162 add_server_manager_handler to add it.
163
164 In the future, this could be expanded to save or serve archive files.
165
166 Args:
167 request: an ArchivedHttpRequest instance
168 url_suffix: string that is after the handler prefix (e.g. 'record')
169 Returns:
170 On a match, an ArchivedHttpResponse.
171 Otherwise, None.
172 """
173 command = url_suffix
174 if command == 'record':
175 self.server_manager.SetRecordMode()
176 return SimpleResponse(200)
177 elif command == 'replay':
178 self.server_manager.SetReplayMode()
179 return SimpleResponse(200)
180 elif command == 'status':
181 is_record_mode = self.server_manager.IsRecordMode()
182 return JsonResponse({'is_record_mode': is_record_mode})
183 return None
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698