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

Side by Side Diff: net/tools/testserver/testserver.py

Issue 1203983004: Stop using SpawnedTestServer in DownloadContentTest.* (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: MSVC doesn't want to make default move constructors either. Created 5 years 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
« no previous file with comments | « net/test/embedded_test_server/default_handlers.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2013 The Chromium Authors. All rights reserved. 2 # Copyright 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """This is a simple HTTP/FTP/TCP/UDP/BASIC_AUTH_PROXY/WEBSOCKET server used for 6 """This is a simple HTTP/FTP/TCP/UDP/BASIC_AUTH_PROXY/WEBSOCKET server used for
7 testing Chrome. 7 testing Chrome.
8 8
9 It supports several test URLs, as specified by the handlers in TestPageHandler. 9 It supports several test URLs, as specified by the handlers in TestPageHandler.
10 By default, it listens on an ephemeral port and sends the port number back to 10 By default, it listens on an ephemeral port and sends the port number back to
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 self.NoContentHandler, 336 self.NoContentHandler,
337 self.ServerRedirectHandler, 337 self.ServerRedirectHandler,
338 self.CrossSiteRedirectHandler, 338 self.CrossSiteRedirectHandler,
339 self.ClientRedirectHandler, 339 self.ClientRedirectHandler,
340 self.GetSSLSessionCacheHandler, 340 self.GetSSLSessionCacheHandler,
341 self.SSLManySmallRecords, 341 self.SSLManySmallRecords,
342 self.GetChannelID, 342 self.GetChannelID,
343 self.GetClientCert, 343 self.GetClientCert,
344 self.ClientCipherListHandler, 344 self.ClientCipherListHandler,
345 self.CloseSocketHandler, 345 self.CloseSocketHandler,
346 self.RangeResetHandler,
347 self.DefaultResponseHandler] 346 self.DefaultResponseHandler]
348 post_handlers = [ 347 post_handlers = [
349 self.EchoTitleHandler, 348 self.EchoTitleHandler,
350 self.EchoHandler, 349 self.EchoHandler,
351 self.PostOnlyFileHandler, 350 self.PostOnlyFileHandler,
352 self.EchoMultipartPostHandler] + get_handlers 351 self.EchoMultipartPostHandler] + get_handlers
353 put_handlers = [ 352 put_handlers = [
354 self.EchoTitleHandler, 353 self.EchoTitleHandler,
355 self.EchoHandler] + get_handlers 354 self.EchoHandler] + get_handlers
356 head_handlers = [ 355 head_handlers = [
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1553 1552
1554 def CloseSocketHandler(self): 1553 def CloseSocketHandler(self):
1555 """Closes the socket without sending anything.""" 1554 """Closes the socket without sending anything."""
1556 1555
1557 if not self._ShouldHandleRequest('/close-socket'): 1556 if not self._ShouldHandleRequest('/close-socket'):
1558 return False 1557 return False
1559 1558
1560 self.wfile.close() 1559 self.wfile.close()
1561 return True 1560 return True
1562 1561
1563 def RangeResetHandler(self):
1564 """Send data broken up by connection resets every N (default 4K) bytes.
1565 Support range requests. If the data requested doesn't straddle a reset
1566 boundary, it will all be sent. Used for testing resuming downloads."""
1567
1568 def DataForRange(start, end):
1569 """Data to be provided for a particular range of bytes."""
1570 # Offset and scale to avoid too obvious (and hence potentially
1571 # collidable) data.
1572 return ''.join([chr(y % 256)
1573 for y in range(start * 2 + 15, end * 2 + 15, 2)])
1574
1575 if not self._ShouldHandleRequest('/rangereset'):
1576 return False
1577
1578 # HTTP/1.1 is required for ETag and range support.
1579 self.protocol_version = 'HTTP/1.1'
1580 _, _, url_path, _, query, _ = urlparse.urlparse(self.path)
1581
1582 # Defaults
1583 size = 8000
1584 # Note that the rst is sent just before sending the rst_boundary byte.
1585 rst_boundary = 4000
1586 respond_to_range = True
1587 hold_for_signal = False
1588 rst_limit = -1
1589 token = 'DEFAULT'
1590 fail_precondition = 0
1591 send_verifiers = True
1592
1593 # Parse the query
1594 qdict = urlparse.parse_qs(query, True)
1595 if 'size' in qdict:
1596 size = int(qdict['size'][0])
1597 if 'rst_boundary' in qdict:
1598 rst_boundary = int(qdict['rst_boundary'][0])
1599 if 'token' in qdict:
1600 # Identifying token for stateful tests.
1601 token = qdict['token'][0]
1602 if 'rst_limit' in qdict:
1603 # Max number of rsts for a given token.
1604 rst_limit = int(qdict['rst_limit'][0])
1605 if 'bounce_range' in qdict:
1606 respond_to_range = False
1607 if 'hold' in qdict:
1608 # Note that hold_for_signal will not work with null range requests;
1609 # see TODO below.
1610 hold_for_signal = True
1611 if 'no_verifiers' in qdict:
1612 send_verifiers = False
1613 if 'fail_precondition' in qdict:
1614 fail_precondition = int(qdict['fail_precondition'][0])
1615
1616 # Record already set information, or set it.
1617 rst_limit = TestPageHandler.rst_limits.setdefault(token, rst_limit)
1618 if rst_limit != 0:
1619 TestPageHandler.rst_limits[token] -= 1
1620 fail_precondition = TestPageHandler.fail_precondition.setdefault(
1621 token, fail_precondition)
1622 if fail_precondition != 0:
1623 TestPageHandler.fail_precondition[token] -= 1
1624
1625 first_byte = 0
1626 last_byte = size - 1
1627
1628 # Does that define what we want to return, or do we need to apply
1629 # a range?
1630 range_response = False
1631 range_header = self.headers.getheader('range')
1632
1633 if fail_precondition and self.headers.getheader('If-Range'):
1634 # Failing a precondition for an If-Range just means that we are going to
1635 # return the entire entity ignoring the Range header.
1636 respond_to_range = False
1637
1638 if range_header and respond_to_range:
1639 mo = re.match("bytes=(\d*)-(\d*)", range_header)
1640 if mo.group(1):
1641 first_byte = int(mo.group(1))
1642 if mo.group(2):
1643 last_byte = int(mo.group(2))
1644 if last_byte > size - 1:
1645 last_byte = size - 1
1646 range_response = True
1647 if last_byte < first_byte:
1648 return False
1649
1650 if range_response:
1651 self.send_response(206)
1652 self.send_header('Content-Range',
1653 'bytes %d-%d/%d' % (first_byte, last_byte, size))
1654 else:
1655 self.send_response(200)
1656 self.send_header('Content-Type', 'application/octet-stream')
1657 self.send_header('Content-Length', last_byte - first_byte + 1)
1658 if send_verifiers:
1659 # If fail_precondition is non-zero, then the ETag for each request will be
1660 # different.
1661 etag = "%s%d" % (token, fail_precondition)
1662 self.send_header('ETag', etag)
1663 self.send_header('Last-Modified', 'Tue, 19 Feb 2013 14:32 EST')
1664 self.end_headers()
1665
1666 if hold_for_signal:
1667 # TODO(rdsmith/phajdan.jr): http://crbug.com/169519: Without writing
1668 # a single byte, the self.server.handle_request() below hangs
1669 # without processing new incoming requests.
1670 self.wfile.write(DataForRange(first_byte, first_byte + 1))
1671 first_byte = first_byte + 1
1672 # handle requests until one of them clears this flag.
1673 self.server.wait_for_download = True
1674 while self.server.wait_for_download:
1675 self.server.handle_request()
1676
1677 possible_rst = ((first_byte / rst_boundary) + 1) * rst_boundary
1678 if possible_rst >= last_byte or rst_limit == 0:
1679 # No RST has been requested in this range, so we don't need to
1680 # do anything fancy; just write the data and let the python
1681 # infrastructure close the connection.
1682 self.wfile.write(DataForRange(first_byte, last_byte + 1))
1683 self.wfile.flush()
1684 return True
1685
1686 # We're resetting the connection part way in; go to the RST
1687 # boundary and then send an RST.
1688 # Because socket semantics do not guarantee that all the data will be
1689 # sent when using the linger semantics to hard close a socket,
1690 # we send the data and then wait for our peer to release us
1691 # before sending the reset.
1692 data = DataForRange(first_byte, possible_rst)
1693 self.wfile.write(data)
1694 self.wfile.flush()
1695 self.server.wait_for_download = True
1696 while self.server.wait_for_download:
1697 self.server.handle_request()
1698 l_onoff = 1 # Linger is active.
1699 l_linger = 0 # Seconds to linger for.
1700 self.connection.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
1701 struct.pack('ii', l_onoff, l_linger))
1702
1703 # Close all duplicates of the underlying socket to force the RST.
1704 self.wfile.close()
1705 self.rfile.close()
1706 self.connection.close()
1707
1708 return True
1709
1710 def DefaultResponseHandler(self): 1562 def DefaultResponseHandler(self):
1711 """This is the catch-all response handler for requests that aren't handled 1563 """This is the catch-all response handler for requests that aren't handled
1712 by one of the special handlers above. 1564 by one of the special handlers above.
1713 Note that we specify the content-length as without it the https connection 1565 Note that we specify the content-length as without it the https connection
1714 is not closed properly (and the browser keeps expecting data).""" 1566 is not closed properly (and the browser keeps expecting data)."""
1715 1567
1716 contents = "Default response given for path: " + self.path 1568 contents = "Default response given for path: " + self.path
1717 self.send_response(200) 1569 self.send_response(200)
1718 self.send_header('Content-Type', 'text/html') 1570 self.send_header('Content-Type', 'text/html')
1719 self.send_header('Content-Length', len(contents)) 1571 self.send_header('Content-Length', len(contents))
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after
2309 'an anonymous user.') 2161 'an anonymous user.')
2310 self.option_parser.add_option('--disable-channel-id', action='store_true') 2162 self.option_parser.add_option('--disable-channel-id', action='store_true')
2311 self.option_parser.add_option('--disable-extended-master-secret', 2163 self.option_parser.add_option('--disable-extended-master-secret',
2312 action='store_true') 2164 action='store_true')
2313 self.option_parser.add_option('--token-binding-params', action='append', 2165 self.option_parser.add_option('--token-binding-params', action='append',
2314 default=[], type='int') 2166 default=[], type='int')
2315 2167
2316 2168
2317 if __name__ == '__main__': 2169 if __name__ == '__main__':
2318 sys.exit(ServerRunner().main()) 2170 sys.exit(ServerRunner().main())
OLDNEW
« no previous file with comments | « net/test/embedded_test_server/default_handlers.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698