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

Side by Side Diff: util/net/http_transport_test_server.py

Issue 692963002: Add HTTPTransport, a Mac implementation, and an end-to-end test. (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Created 6 years, 1 month 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
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright 2014 The Crashpad Authors. All rights reserved.
Mark Mentovai 2014/10/30 21:13:55 Gimme a blank line before this.
Robert Sesek 2014/10/31 14:48:15 Done.
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 """A one-shot testing webserver.
17
18 When invoked, this server will write an integer to stdout, indiciating on which
19 port the server is listening. It will then read one integer from stdin,
20 indiciating the response code to set for a request. The server will process
21 one HTTP request, writing it out entirely to stdout, and will then terminate.
Mark Mentovai 2014/10/30 21:13:55 Do you want to say up here that the main motivatio
Robert Sesek 2014/10/31 14:48:15 Done.
22 """
23
24 import BaseHTTPServer
25 import struct
26 import sys
27
28 class BufferedReadFile(object):
29 """A File-like object that stores all read contents into a buffer."""
30
31 def __init__(self, real_file):
32 self.file = real_file
33 self.buffer = ""
34
35 def read(self, size=-1):
36 buf = self.file.read(size)
37 self.buffer += buf
38 return buf
39
40 def readline(self, size=-1):
41 buf = self.file.readline(size)
42 self.buffer += buf
43 return buf
44
45 def flush(self):
46 self.file.flush()
47
48 def close(self):
49 self.file.close()
50
51
52 class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
53 response_code = 500
54
55 def handle_one_request(self):
56 # Wrap the rfile in the buffering file object so that the raw header block
57 # can be written to stdout after it is parsed.
58 self.rfile = BufferedReadFile(self.rfile)
59 BaseHTTPServer.BaseHTTPRequestHandler.handle_one_request(self)
60
61 def do_POST(self):
62 writer = sys.stdout
63
64 writer.write(self.rfile.buffer)
65 self.rfile.buffer = ''
66
67 if self.headers.get('Transfer-Encoding', '') == 'Chunked':
68 body = self.handle_chunked_encoding()
69 else:
70 length = int(self.headers['Content-Length'])
Mark Mentovai 2014/10/30 21:13:55 This field may not be present. If it’s not, you sh
Robert Sesek 2014/10/31 14:48:15 Done.
71 body = self.rfile.read(length)
72
73 self.send_response(self.response_code)
74 writer.write(body)
75 writer.flush()
76
77 def handle_chunked_encoding(self):
78 """This parses a "Transfer-Encoding: Chunked" body in accordance with
79 <http://tools.ietf.org/html/rfc7230#section-4.1>. This returns the result
Mark Mentovai 2014/10/30 21:13:55 RFCs are pretty canonical, you don’t need a link,
Robert Sesek 2014/10/31 14:48:15 Done.
80 as a string.
81 """
82 body = ''
83 chunk_size = self.read_chunk_size()
84 while chunk_size > 0:
85 # Read the body.
86 data = self.rfile.read(chunk_size)
87 chunk_size -= len(data)
88 body += data
89
90 # Finished reading this chunk.
91 if chunk_size == 0:
92 # Read through any trailer fields.
93 trailer_line = self.rfile.readline()
94 while trailer_line.strip() != '':
95 trailer_line = self.rfile.readline()
96
97 # Read the chunk size.
98 chunk_size = self.read_chunk_size()
99 return body
100
101 def read_chunk_size(self):
102 # Read the whole line, including the \r\n.
103 chunk_size_and_ext_line = self.rfile.readline()
104 # Look for a chunk extension.
105 chunk_size_end = chunk_size_and_ext_line.find(';')
106 if chunk_size_end == -1:
107 # No chunk extensions; just encounter the end of line.
108 chunk_size_end = chunk_size_and_ext_line.find('\r')
109 if chunk_size_end == -1:
110 self.send_response(400) # Bad request.
111 return -1
112 return int(chunk_size_and_ext_line[:chunk_size_end], base=16)
113
114
115 def Main():
116 # Start the server.
117 server = BaseHTTPServer.HTTPServer(('127.0.0.1', 0), RequestHandler)
118
119 # Write the port as an int to the parent process.
120 sys.stdout.write(struct.pack('i', server.server_address[1]))
121 sys.stdout.flush()
122
123 # Read the desired test response code from the parent process.
124 RequestHandler.response_code = \
125 struct.unpack('i', sys.stdin.read(struct.calcsize('i')))[0]
126
127 # Handle the request.
128 server.handle_request()
129
130 if __name__ == '__main__':
131 Main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698