xhr_benchmark_handler.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. # Copyright 2014 Google Inc. All rights reserved.
  2. #
  3. # Use of this source code is governed by a BSD-style
  4. # license that can be found in the COPYING file or at
  5. # https://developers.google.com/open-source/licenses/bsd
  6. from mod_pywebsocket import util
  7. class XHRBenchmarkHandler(object):
  8. def __init__(self, headers, rfile, wfile):
  9. self._logger = util.get_class_logger(self)
  10. self.headers = headers
  11. self.rfile = rfile
  12. self.wfile = wfile
  13. def do_send(self):
  14. content_length = int(self.headers.getheader('Content-Length'))
  15. self._logger.debug('Requested to receive %s bytes', content_length)
  16. RECEIVE_BLOCK_SIZE = 1024 * 1024
  17. bytes_to_receive = content_length
  18. while bytes_to_receive > 0:
  19. bytes_to_receive_in_this_loop = bytes_to_receive
  20. if bytes_to_receive_in_this_loop > RECEIVE_BLOCK_SIZE:
  21. bytes_to_receive_in_this_loop = RECEIVE_BLOCK_SIZE
  22. received_data = self.rfile.read(bytes_to_receive_in_this_loop)
  23. if received_data != ('a' * bytes_to_receive_in_this_loop):
  24. self._logger.debug('Request body verification failed')
  25. return
  26. bytes_to_receive -= len(received_data)
  27. if bytes_to_receive < 0:
  28. self._logger.debug('Received %d more bytes than expected' %
  29. (-bytes_to_receive))
  30. return
  31. # Return the number of received bytes back to the client.
  32. response_body = '%d' % content_length
  33. self.wfile.write(
  34. 'HTTP/1.1 200 OK\r\n'
  35. 'Content-Type: text/html\r\n'
  36. 'Content-Length: %d\r\n'
  37. '\r\n%s' % (len(response_body), response_body))
  38. self.wfile.flush()
  39. def do_receive(self):
  40. content_length = int(self.headers.getheader('Content-Length'))
  41. request_body = self.rfile.read(content_length)
  42. request_array = request_body.split(' ')
  43. if len(request_array) < 2:
  44. self._logger.debug('Malformed request body: %r', request_body)
  45. return
  46. # Parse the size parameter.
  47. bytes_to_send = request_array[0]
  48. try:
  49. bytes_to_send = int(bytes_to_send)
  50. except ValueError, e:
  51. self._logger.debug('Malformed size parameter: %r', bytes_to_send)
  52. return
  53. self._logger.debug('Requested to send %s bytes', bytes_to_send)
  54. # Parse the transfer encoding parameter.
  55. chunked_mode = False
  56. mode_parameter = request_array[1]
  57. if mode_parameter == 'chunked':
  58. self._logger.debug('Requested chunked transfer encoding')
  59. chunked_mode = True
  60. elif mode_parameter != 'none':
  61. self._logger.debug('Invalid mode parameter: %r', mode_parameter)
  62. return
  63. # Write a header
  64. response_header = (
  65. 'HTTP/1.1 200 OK\r\n'
  66. 'Content-Type: application/octet-stream\r\n')
  67. if chunked_mode:
  68. response_header += 'Transfer-Encoding: chunked\r\n\r\n'
  69. else:
  70. response_header += (
  71. 'Content-Length: %d\r\n\r\n' % bytes_to_send)
  72. self.wfile.write(response_header)
  73. self.wfile.flush()
  74. # Write a body
  75. SEND_BLOCK_SIZE = 1024 * 1024
  76. while bytes_to_send > 0:
  77. bytes_to_send_in_this_loop = bytes_to_send
  78. if bytes_to_send_in_this_loop > SEND_BLOCK_SIZE:
  79. bytes_to_send_in_this_loop = SEND_BLOCK_SIZE
  80. if chunked_mode:
  81. self.wfile.write('%x\r\n' % bytes_to_send_in_this_loop)
  82. self.wfile.write('a' * bytes_to_send_in_this_loop)
  83. if chunked_mode:
  84. self.wfile.write('\r\n')
  85. self.wfile.flush()
  86. bytes_to_send -= bytes_to_send_in_this_loop
  87. if chunked_mode:
  88. self.wfile.write('0\r\n\r\n')
  89. self.wfile.flush()