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

Side by Side Diff: platform_tools/nacl/httpd.py

Issue 1036283002: Remove all code related to NaCl (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rebase Created 5 years, 8 months 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 | « platform_tools/nacl/favicon.ico ('k') | platform_tools/nacl/index.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """A tiny web server.
7
8 This is intended to be used for testing, and only run from within the examples
9 directory.
10 """
11
12 import BaseHTTPServer
13 import logging
14 import optparse
15 import os
16 import SimpleHTTPServer
17 import SocketServer
18 import sys
19 import urlparse
20
21
22 EXAMPLE_PATH=os.path.dirname(os.path.abspath(__file__))
23 NACL_SDK_ROOT = os.getenv('NACL_SDK_ROOT', os.path.dirname(EXAMPLE_PATH))
24
25
26 if os.path.exists(NACL_SDK_ROOT):
27 sys.path.append(os.path.join(NACL_SDK_ROOT, 'tools'))
28 import decode_dump
29 import getos
30 else:
31 NACL_SDK_ROOT=None
32
33 last_nexe = None
34 last_nmf = None
35
36 logging.getLogger().setLevel(logging.INFO)
37
38 # Using 'localhost' means that we only accept connections
39 # via the loop back interface.
40 SERVER_PORT = 5103
41 SERVER_HOST = ''
42
43 # We only run from the examples directory so that not too much is exposed
44 # via this HTTP server. Everything in the directory is served, so there should
45 # never be anything potentially sensitive in the serving directory, especially
46 # if the machine might be a multi-user machine and not all users are trusted.
47 # We only serve via the loopback interface.
48 def SanityCheckDirectory():
49 httpd_path = os.path.abspath(os.path.dirname(__file__))
50 serve_path = os.path.abspath(os.getcwd())
51
52 # Verify we are serving from the directory this script came from, or bellow
53 if serve_path[:len(httpd_path)] == httpd_path:
54 return
55 logging.error('For security, httpd.py should only be run from within the')
56 logging.error('example directory tree.')
57 logging.error('We are currently in %s.' % serve_path)
58 sys.exit(1)
59
60
61 # An HTTP server that will quit when |is_running| is set to False. We also use
62 # SocketServer.ThreadingMixIn in order to handle requests asynchronously for
63 # faster responses.
64 class QuittableHTTPServer(SocketServer.ThreadingMixIn,
65 BaseHTTPServer.HTTPServer):
66 def serve_forever(self, timeout=0.5):
67 self.is_running = True
68 self.timeout = timeout
69 while self.is_running:
70 self.handle_request()
71
72 def shutdown(self):
73 self.is_running = False
74 return 1
75
76
77 # "Safely" split a string at |sep| into a [key, value] pair. If |sep| does not
78 # exist in |str|, then the entire |str| is the key and the value is set to an
79 # empty string.
80 def KeyValuePair(str, sep='='):
81 if sep in str:
82 return str.split(sep)
83 else:
84 return [str, '']
85
86
87 # A small handler that looks for '?quit=1' query in the path and shuts itself
88 # down if it finds that parameter.
89 class QuittableHTTPHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
90 def send_head(self):
91 """Common code for GET and HEAD commands.
92
93 This sends the response code and MIME headers.
94
95 Return value is either a file object (which has to be copied
96 to the outputfile by the caller unless the command was HEAD,
97 and must be closed by the caller under all circumstances), or
98 None, in which case the caller has nothing further to do.
99
100 """
101 path = self.translate_path(self.path)
102 f = None
103 if os.path.isdir(path):
104 if not self.path.endswith('/'):
105 # redirect browser - doing basically what apache does
106 self.send_response(301)
107 self.send_header("Location", self.path + "/")
108 self.end_headers()
109 return None
110 for index in "index.html", "index.htm":
111 index = os.path.join(path, index)
112 if os.path.exists(index):
113 path = index
114 break
115 else:
116 return self.list_directory(path)
117 ctype = self.guess_type(path)
118 try:
119 # Always read in binary mode. Opening files in text mode may cause
120 # newline translations, making the actual size of the content
121 # transmitted *less* than the content-length!
122 f = open(path, 'rb')
123 except IOError:
124 self.send_error(404, "File not found")
125 return None
126 self.send_response(200)
127 self.send_header("Content-type", ctype)
128 fs = os.fstat(f.fileno())
129 self.send_header("Content-Length", str(fs[6]))
130 self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
131 self.send_header('Cache-Control','no-cache, must-revalidate')
132 self.send_header('Expires','-1')
133 self.end_headers()
134 return f
135
136 def do_GET(self):
137 global last_nexe, last_nmf
138 (_, _, path, query, _) = urlparse.urlsplit(self.path)
139 url_params = dict([KeyValuePair(key_value)
140 for key_value in query.split('&')])
141 if 'quit' in url_params and '1' in url_params['quit']:
142 self.send_response(200, 'OK')
143 self.send_header('Content-type', 'text/html')
144 self.send_header('Content-length', '0')
145 self.end_headers()
146 self.server.shutdown()
147 return
148
149 if path.endswith('.nexe'):
150 last_nexe = path
151 if path.endswith('.nmf'):
152 last_nmf = path
153
154 SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
155
156 def do_POST(self):
157 (_, _,path, query, _) = urlparse.urlsplit(self.path)
158 if 'Content-Length' in self.headers:
159 if not NACL_SDK_ROOT:
160 self.wfile('Could not find NACL_SDK_ROOT to decode trace.')
161 return
162 data = self.rfile.read(int(self.headers['Content-Length']))
163 nexe = '.' + last_nexe
164 nmf = '.' + last_nmf
165 addr = os.path.join(NACL_SDK_ROOT, 'toolchain',
166 getos.GetPlatform() + '_x86_newlib',
167 'bin', 'x86_64-nacl-addr2line')
168 decoder = decode_dump.CoreDecoder(nexe, nmf, addr, None, None)
169 info = decoder.Decode(data)
170 trace = decoder.StackTrace(info)
171 decoder.PrintTrace(trace, sys.stdout)
172 decoder.PrintTrace(trace, self.wfile)
173
174
175 def Run(server_address,
176 server_class=QuittableHTTPServer,
177 handler_class=QuittableHTTPHandler):
178 httpd = server_class(server_address, handler_class)
179 logging.info("Starting local server on port %d", server_address[1])
180 logging.info("To shut down send http://localhost:%d?quit=1",
181 server_address[1])
182 try:
183 httpd.serve_forever()
184 except KeyboardInterrupt:
185 logging.info("Received keyboard interrupt.")
186 httpd.server_close()
187
188 logging.info("Shutting down local server on port %d", server_address[1])
189
190
191 def main():
192 usage_str = "usage: %prog [options] [optional_portnum]"
193 parser = optparse.OptionParser(usage=usage_str)
194 parser.add_option(
195 '--no_dir_check', dest='do_safe_check',
196 action='store_false', default=True,
197 help='Do not ensure that httpd.py is being run from a safe directory.')
198 (options, args) = parser.parse_args(sys.argv)
199 if options.do_safe_check:
200 SanityCheckDirectory()
201 if len(args) > 2:
202 print 'Too many arguments specified.'
203 parser.print_help()
204 elif len(args) == 2:
205 Run((SERVER_HOST, int(args[1])))
206 else:
207 Run((SERVER_HOST, SERVER_PORT))
208 return 0
209
210
211 if __name__ == '__main__':
212 sys.exit(main())
OLDNEW
« no previous file with comments | « platform_tools/nacl/favicon.ico ('k') | platform_tools/nacl/index.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698