blob: 7f49a8db87018005a46c70e7657f8f7002ce2c22 [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Testserver for the two phase upload protocol."""
import base64
import BaseHTTPServer
import hashlib
import os
import sys
import urlparse
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(BASE_DIR, '..', '..', '..', '..', 'net',
'tools', 'testserver'))
import testserver_base
class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def ReadRequestBody(self):
"""This function reads the body of the current HTTP request, handling
both plain and chunked transfer encoded requests."""
if self.headers.getheader('transfer-encoding') == 'chunked':
return ''
length = int(self.headers.getheader('content-length'))
return self.rfile.read(length)
def do_GET(self):
print 'GET', self.path
self.send_error(400, 'GET not supported')
def do_POST(self):
request_body = self.ReadRequestBody()
print 'POST', repr(self.path), repr(request_body)
kStartHeader = 'x-goog-resumable'
if kStartHeader not in self.headers:
self.send_error(400, 'Missing header: ' + kStartHeader)
return
if self.headers.get(kStartHeader) != 'start':
self.send_error(400, 'Invalid %s header value: %s' % (
kStartHeader, self.headers.get(kStartHeader)))
return
metadata_hash = hashlib.sha1(request_body).hexdigest()
_, _, url_path, _, query, _ = urlparse.urlparse(self.path)
query_args = urlparse.parse_qs(query)
if query_args.get('p1close'):
self.close_connection = 1
return
put_url = 'http://%s:%d/put?%s,%s,%s' % (self.server.server_address[0],
self.server.server_port,
url_path,
metadata_hash,
base64.urlsafe_b64encode(query))
self.send_response(int(query_args.get('p1code', [201])[0]))
self.send_header('Location', put_url)
self.end_headers()
def do_PUT(self):
_, _, url_path, _, query, _ = urlparse.urlparse(self.path)
if url_path != '/put':
self.send_error(400, 'invalid path on 2nd phase: ' + url_path)
return
initial_path, metadata_hash, config_query_b64 = query.split(',', 2)
config_query = urlparse.parse_qs(base64.urlsafe_b64decode(config_query_b64))
request_body = self.ReadRequestBody()
print 'PUT', repr(self.path), len(request_body), 'bytes'
if config_query.get('p2close'):
self.close_connection = 1
return
self.send_response(int(config_query.get('p2code', [200])[0]))
self.end_headers()
self.wfile.write('%s\n%s\n%s\n' % (
initial_path,
metadata_hash,
hashlib.sha1(request_body).hexdigest()))
class ServerRunner(testserver_base.TestServerRunner):
"""TestServerRunner for safebrowsing_test_server.py."""
def create_server(self, server_data):
server = BaseHTTPServer.HTTPServer((self.options.host, self.options.port),
RequestHandler)
print 'server started on port %d...' % server.server_port
server_data['port'] = server.server_port
return server
if __name__ == '__main__':
sys.exit(ServerRunner().main())