def __init__(self, server_address, xmpp_port, request_handler_class): testserver_base.StoppableHTTPServer.__init__(self, server_address, request_handler_class) self._sync_handler = chromiumsync.TestServer() self._xmpp_socket_map = {} self._xmpp_server = xmppserver.XmppServer(self._xmpp_socket_map, ('localhost', xmpp_port)) self.xmpp_port = self._xmpp_server.getsockname()[1] self.authenticated = True
def testCheckRaiseTransientError(self): testserver = chromiumsync.TestServer() http_code, raw_respon = testserver.HandleSetTransientError() self.assertEqual(http_code, 200) try: testserver.CheckTransientError() self.fail('Should have raised transient error exception') except chromiumsync.TransientError: self.assertTrue(testserver.transient_error)
class TestPageHandler(BaseHTTPServer.BaseHTTPRequestHandler): def __init__(self, request, client_address, socket_server): self._connect_handlers = [ self.RedirectConnectHandler, self.ServerAuthConnectHandler, self.DefaultConnectResponseHandler ] self._get_handlers = [ self.KillHandler, self.NoCacheMaxAgeTimeHandler, self.NoCacheTimeHandler, self.CacheTimeHandler, self.CacheExpiresHandler, self.CacheProxyRevalidateHandler, self.CachePrivateHandler, self.CachePublicHandler, self.CacheSMaxAgeHandler, self.CacheMustRevalidateHandler, self.CacheMustRevalidateMaxAgeHandler, self.CacheNoStoreHandler, self.CacheNoStoreMaxAgeHandler, self.CacheNoTransformHandler, self.DownloadHandler, self.DownloadFinishHandler, self.EchoHeader, self.EchoHeaderOverride, self.EchoAllHandler, self.FileHandler, self.RealFileWithCommonHeaderHandler, self.RealBZ2FileWithCommonHeaderHandler, self.SetCookieHandler, self.AuthBasicHandler, self.AuthDigestHandler, self.SlowServerHandler, self.ContentTypeHandler, self.ServerRedirectHandler, self.ClientRedirectHandler, self.ChromiumSyncTimeHandler, self.MultipartHandler, self.DefaultResponseHandler ] self._post_handlers = [ self.WriteFile, self.EchoTitleHandler, self.EchoAllHandler, self.ChromiumSyncCommandHandler, self.EchoHandler ] + self._get_handlers self._put_handlers = [ self.WriteFile, self.EchoTitleHandler, self.EchoAllHandler, self.EchoHandler ] + self._get_handlers self._mime_types = { 'gif': 'image/gif', 'jpeg': 'image/jpeg', 'jpg': 'image/jpeg', 'xml': 'text/xml' } self._default_mime_type = 'text/html' BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, request, client_address, socket_server) # Class variable; shared across requests. _sync_handler = chromiumsync.TestServer() def _ShouldHandleRequest(self, handler_name): """Determines if the path can be handled by the handler. We consider a handler valid if the path begins with the handler name. It can optionally be followed by "?*", "/*". """ pattern = re.compile('%s($|\?|/).*' % handler_name) return pattern.match(self.path) def GetMIMETypeFromName(self, file_name): """Returns the mime type for the specified file_name. So far it only looks at the file extension.""" (shortname, extension) = os.path.splitext(file_name) if len(extension) == 0: # no extension. return self._default_mime_type # extension starts with a dot, so we need to remove it return self._mime_types.get(extension[1:], self._default_mime_type) def KillHandler(self): """This request handler kills the server, for use when we're done" with the a particular test.""" if (self.path.find("kill") < 0): return False self.send_response(200) self.send_header('Content-type', 'text/html') self.send_header('Cache-Control', 'max-age=0') self.end_headers() if options.never_die: self.wfile.write('I cannot die!! BWAHAHA') else: self.wfile.write('Goodbye cruel world!') self.server.stop = True return True def NoCacheMaxAgeTimeHandler(self): """This request handler yields a page with the title set to the current system time, and no caching requested.""" if not self._ShouldHandleRequest("/nocachetime/maxage"): return False self.send_response(200) self.send_header('Cache-Control', 'max-age=0') self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write('<html><head><title>%s</title></head></html>' % time.time()) return True def NoCacheTimeHandler(self): """This request handler yields a page with the title set to the current system time, and no caching requested.""" if not self._ShouldHandleRequest("/nocachetime"): return False self.send_response(200) self.send_header('Cache-Control', 'no-cache') self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write('<html><head><title>%s</title></head></html>' % time.time()) return True def CacheTimeHandler(self): """This request handler yields a page with the title set to the current system time, and allows caching for one minute.""" if not self._ShouldHandleRequest("/cachetime"): return False self.send_response(200) self.send_header('Cache-Control', 'max-age=60') self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write('<html><head><title>%s</title></head></html>' % time.time()) return True def CacheExpiresHandler(self): """This request handler yields a page with the title set to the current system time, and set the page to expire on 1 Jan 2099.""" if not self._ShouldHandleRequest("/cache/expires"): return False self.send_response(200) self.send_header('Expires', 'Thu, 1 Jan 2099 00:00:00 GMT') self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write('<html><head><title>%s</title></head></html>' % time.time()) return True def CacheProxyRevalidateHandler(self): """This request handler yields a page with the title set to the current system time, and allows caching for 60 seconds""" if not self._ShouldHandleRequest("/cache/proxy-revalidate"): return False self.send_response(200) self.send_header('Content-type', 'text/html') self.send_header('Cache-Control', 'max-age=60, proxy-revalidate') self.end_headers() self.wfile.write('<html><head><title>%s</title></head></html>' % time.time()) return True def CachePrivateHandler(self): """This request handler yields a page with the title set to the current system time, and allows caching for 5 seconds.""" if not self._ShouldHandleRequest("/cache/private"): return False self.send_response(200) self.send_header('Content-type', 'text/html') self.send_header('Cache-Control', 'max-age=3, private') self.end_headers() self.wfile.write('<html><head><title>%s</title></head></html>' % time.time()) return True def CachePublicHandler(self): """This request handler yields a page with the title set to the current system time, and allows caching for 5 seconds.""" if not self._ShouldHandleRequest("/cache/public"): return False self.send_response(200) self.send_header('Content-type', 'text/html') self.send_header('Cache-Control', 'max-age=3, public') self.end_headers() self.wfile.write('<html><head><title>%s</title></head></html>' % time.time()) return True def CacheSMaxAgeHandler(self): """This request handler yields a page with the title set to the current system time, and does not allow for caching.""" if not self._ShouldHandleRequest("/cache/s-maxage"): return False self.send_response(200) self.send_header('Content-type', 'text/html') self.send_header('Cache-Control', 'public, s-maxage = 60, max-age = 0') self.end_headers() self.wfile.write('<html><head><title>%s</title></head></html>' % time.time()) return True def CacheMustRevalidateHandler(self): """This request handler yields a page with the title set to the current system time, and does not allow caching.""" if not self._ShouldHandleRequest("/cache/must-revalidate"): return False self.send_response(200) self.send_header('Content-type', 'text/html') self.send_header('Cache-Control', 'must-revalidate') self.end_headers() self.wfile.write('<html><head><title>%s</title></head></html>' % time.time()) return True def CacheMustRevalidateMaxAgeHandler(self): """This request handler yields a page with the title set to the current system time, and does not allow caching event though max-age of 60 seconds is specified.""" if not self._ShouldHandleRequest("/cache/must-revalidate/max-age"): return False self.send_response(200) self.send_header('Content-type', 'text/html') self.send_header('Cache-Control', 'max-age=60, must-revalidate') self.end_headers() self.wfile.write('<html><head><title>%s</title></head></html>' % time.time()) return True def CacheNoStoreHandler(self): """This request handler yields a page with the title set to the current system time, and does not allow the page to be stored.""" if not self._ShouldHandleRequest("/cache/no-store"): return False self.send_response(200) self.send_header('Content-type', 'text/html') self.send_header('Cache-Control', 'no-store') self.end_headers() self.wfile.write('<html><head><title>%s</title></head></html>' % time.time()) return True def CacheNoStoreMaxAgeHandler(self): """This request handler yields a page with the title set to the current system time, and does not allow the page to be stored even though max-age of 60 seconds is specified.""" if not self._ShouldHandleRequest("/cache/no-store/max-age"): return False self.send_response(200) self.send_header('Content-type', 'text/html') self.send_header('Cache-Control', 'max-age=60, no-store') self.end_headers() self.wfile.write('<html><head><title>%s</title></head></html>' % time.time()) return True def CacheNoTransformHandler(self): """This request handler yields a page with the title set to the current system time, and does not allow the content to transformed during user-agent caching""" if not self._ShouldHandleRequest("/cache/no-transform"): return False self.send_response(200) self.send_header('Content-type', 'text/html') self.send_header('Cache-Control', 'no-transform') self.end_headers() self.wfile.write('<html><head><title>%s</title></head></html>' % time.time()) return True def EchoHeader(self): """This handler echoes back the value of a specific request header.""" """The only difference between this function and the EchoHeaderOverride""" """function is in the parameter being passed to the helper function""" return self.EchoHeaderHelper("/echoheader") def EchoHeaderOverride(self): """This handler echoes back the value of a specific request header.""" """The UrlRequest unit tests also execute for ChromeFrame which uses""" """IE to issue HTTP requests using the host network stack.""" """The Accept and Charset tests which expect the server to echo back""" """the corresponding headers fail here as IE returns cached responses""" """The EchoHeaderOverride parameter is an easy way to ensure that IE""" """treats this request as a new request and does not cache it.""" return self.EchoHeaderHelper("/echoheaderoverride") def EchoHeaderHelper(self, echo_header): """This function echoes back the value of the request header passed in.""" if not self._ShouldHandleRequest(echo_header): return False query_char = self.path.find('?') if query_char != -1: header_name = self.path[query_char + 1:] self.send_response(200) self.send_header('Content-type', 'text/plain') self.send_header('Cache-control', 'max-age=60000') # insert a vary header to properly indicate that the cachability of this # request is subject to value of the request header being echoed. if len(header_name) > 0: self.send_header('Vary', header_name) self.end_headers() if len(header_name) > 0: self.wfile.write(self.headers.getheader(header_name)) return True def EchoHandler(self): """This handler just echoes back the payload of the request, for testing form submission.""" if not self._ShouldHandleRequest("/echo"): return False self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() length = int(self.headers.getheader('content-length')) request = self.rfile.read(length) self.wfile.write(request) return True def WriteFile(self): """This is handler dumps the content of POST/PUT request to a disk file into the data_dir/dump. Sub-directories are not supported.""" prefix = '/writefile/' if not self.path.startswith(prefix): return False file_name = self.path[len(prefix):] # do not allow fancy chars in file name re.sub('[^a-zA-Z0-9_.-]+', '', file_name) if len(file_name) and file_name[0] != '.': path = os.path.join(self.server.data_dir, 'dump', file_name) length = int(self.headers.getheader('content-length')) request = self.rfile.read(length) f = open(path, "wb") f.write(request) f.close() self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write('<html>%s</html>' % file_name) return True def EchoTitleHandler(self): """This handler is like Echo, but sets the page title to the request.""" if not self._ShouldHandleRequest("/echotitle"): return False self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() length = int(self.headers.getheader('content-length')) request = self.rfile.read(length) self.wfile.write('<html><head><title>') self.wfile.write(request) self.wfile.write('</title></head></html>') return True def EchoAllHandler(self): """This handler yields a (more) human-readable page listing information about the request header & contents.""" if not self._ShouldHandleRequest("/echoall"): return False self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write( '<html><head><style>' 'pre { border: 1px solid black; margin: 5px; padding: 5px }' '</style></head><body>' '<div style="float: right">' '<a href="http://localhost:8888/echo">back to referring page</a></div>' '<h1>Request Body:</h1><pre>') if self.command == 'POST' or self.command == 'PUT': length = int(self.headers.getheader('content-length')) qs = self.rfile.read(length) params = cgi.parse_qs(qs, keep_blank_values=1) for param in params: self.wfile.write('%s=%s\n' % (param, params[param][0])) self.wfile.write('</pre>') self.wfile.write('<h1>Request Headers:</h1><pre>%s</pre>' % self.headers) self.wfile.write('</body></html>') return True def DownloadHandler(self): """This handler sends a downloadable file with or without reporting the size (6K).""" if self.path.startswith("/download-unknown-size"): send_length = False elif self.path.startswith("/download-known-size"): send_length = True else: return False # # The test which uses this functionality is attempting to send # small chunks of data to the client. Use a fairly large buffer # so that we'll fill chrome's IO buffer enough to force it to # actually write the data. # See also the comments in the client-side of this test in # download_uitest.cc # size_chunk1 = 35 * 1024 size_chunk2 = 10 * 1024 self.send_response(200) self.send_header('Content-type', 'application/octet-stream') self.send_header('Cache-Control', 'max-age=0') if send_length: self.send_header('Content-Length', size_chunk1 + size_chunk2) self.end_headers() # First chunk of data: self.wfile.write("*" * size_chunk1) self.wfile.flush() # handle requests until one of them clears this flag. self.server.waitForDownload = True while self.server.waitForDownload: self.server.handle_request() # Second chunk of data: self.wfile.write("*" * size_chunk2) return True def DownloadFinishHandler(self): """This handler just tells the server to finish the current download.""" if not self._ShouldHandleRequest("/download-finish"): return False self.server.waitForDownload = False self.send_response(200) self.send_header('Content-type', 'text/html') self.send_header('Cache-Control', 'max-age=0') self.end_headers() return True def FileHandler(self): """This handler sends the contents of the requested file. Wow, it's like a real webserver!""" prefix = self.server.file_root_url if not self.path.startswith(prefix): return False # Consume a request body if present. if self.command == 'POST' or self.command == 'PUT': self.rfile.read(int(self.headers.getheader('content-length'))) file = self.path[len(prefix):] if file.find('?') > -1: # Ignore the query parameters entirely. url, querystring = file.split('?') else: url = file entries = url.split('/') path = os.path.join(self.server.data_dir, *entries) if os.path.isdir(path): path = os.path.join(path, 'index.html') if not os.path.isfile(path): print "File not found " + file + " full path:" + path self.send_error(404) return True f = open(path, "rb") data = f.read() f.close() # If file.mock-http-headers exists, it contains the headers we # should send. Read them in and parse them. headers_path = path + '.mock-http-headers' if os.path.isfile(headers_path): f = open(headers_path, "r") # "HTTP/1.1 200 OK" response = f.readline() status_code = re.findall('HTTP/\d+.\d+ (\d+)', response)[0] self.send_response(int(status_code)) for line in f: header_values = re.findall('(\S+):\s*(.*)', line) if len(header_values) > 0: # "name: value" name, value = header_values[0] self.send_header(name, value) f.close() else: # Could be more generic once we support mime-type sniffing, but for # now we need to set it explicitly. self.send_response(200) self.send_header('Content-type', self.GetMIMETypeFromName(file)) self.send_header('Content-Length', len(data)) self.end_headers() self.wfile.write(data) return True def RealFileWithCommonHeaderHandler(self): """This handler sends the contents of the requested file without the pseudo http head!""" prefix = '/realfiles/' if not self.path.startswith(prefix): return False file = self.path[len(prefix):] path = os.path.join(self.server.data_dir, file) try: f = open(path, "rb") data = f.read() f.close() # just simply set the MIME as octal stream self.send_response(200) self.send_header('Content-type', 'application/octet-stream') self.end_headers() self.wfile.write(data) except: self.send_error(404) return True def RealBZ2FileWithCommonHeaderHandler(self): """This handler sends the bzip2 contents of the requested file with corresponding Content-Encoding field in http head!""" prefix = '/realbz2files/' if not self.path.startswith(prefix): return False parts = self.path.split('?') file = parts[0][len(prefix):] path = os.path.join(self.server.data_dir, file) + '.bz2' if len(parts) > 1: options = parts[1] else: options = '' try: self.send_response(200) accept_encoding = self.headers.get("Accept-Encoding") if accept_encoding.find("bzip2") != -1: f = open(path, "rb") data = f.read() f.close() self.send_header('Content-Encoding', 'bzip2') self.send_header('Content-type', 'application/x-bzip2') self.end_headers() if options == 'incremental-header': self.wfile.write(data[:1]) self.wfile.flush() time.sleep(1.0) self.wfile.write(data[1:]) else: self.wfile.write(data) else: """client do not support bzip2 format, send pseudo content """ self.send_header('Content-type', 'text/html; charset=ISO-8859-1') self.end_headers() self.wfile.write("you do not support bzip2 encoding") except: self.send_error(404) return True def SetCookieHandler(self): """This handler just sets a cookie, for testing cookie handling.""" if not self._ShouldHandleRequest("/set-cookie"): return False query_char = self.path.find('?') if query_char != -1: cookie_values = self.path[query_char + 1:].split('&') else: cookie_values = ("", ) self.send_response(200) self.send_header('Content-type', 'text/html') for cookie_value in cookie_values: self.send_header('Set-Cookie', '%s' % cookie_value) self.end_headers() for cookie_value in cookie_values: self.wfile.write('%s' % cookie_value) return True def AuthBasicHandler(self): """This handler tests 'Basic' authentication. It just sends a page with title 'user/pass' if you succeed.""" if not self._ShouldHandleRequest("/auth-basic"): return False username = userpass = password = b64str = "" set_cookie_if_challenged = self.path.find( '?set-cookie-if-challenged') > 0 auth = self.headers.getheader('authorization') try: if not auth: raise Exception('no auth') b64str = re.findall(r'Basic (\S+)', auth)[0] userpass = base64.b64decode(b64str) username, password = re.findall(r'([^:]+):(\S+)', userpass)[0] if password != 'secret': raise Exception('wrong password') except Exception, e: # Authentication failed. self.send_response(401) self.send_header('WWW-Authenticate', 'Basic realm="testrealm"') self.send_header('Content-type', 'text/html') if set_cookie_if_challenged: self.send_header('Set-Cookie', 'got_challenged=true') self.end_headers() self.wfile.write('<html><head>') self.wfile.write('<title>Denied: %s</title>' % e) self.wfile.write('</head><body>') self.wfile.write('auth=%s<p>' % auth) self.wfile.write('b64str=%s<p>' % b64str) self.wfile.write('username: %s<p>' % username) self.wfile.write('userpass: %s<p>' % userpass) self.wfile.write('password: %s<p>' % password) self.wfile.write('You sent:<br>%s<p>' % self.headers) self.wfile.write('</body></html>') return True # Authentication successful. (Return a cachable response to allow for # testing cached pages that require authentication.) if_none_match = self.headers.getheader('if-none-match') if if_none_match == "abc": self.send_response(304) self.end_headers() else: self.send_response(200) self.send_header('Content-type', 'text/html') self.send_header('Cache-control', 'max-age=60000') self.send_header('Etag', 'abc') self.end_headers() self.wfile.write('<html><head>') self.wfile.write('<title>%s/%s</title>' % (username, password)) self.wfile.write('</head><body>') self.wfile.write('auth=%s<p>' % auth) self.wfile.write('You sent:<br>%s<p>' % self.headers) self.wfile.write('</body></html>') return True