- add sources.
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / core / temporary_http_server.py
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4 import os
5 import socket
6 import subprocess
7 import sys
8 import urlparse
9
10 from telemetry.core import util
11
12 class TemporaryHTTPServer(object):
13   def __init__(self, browser_backend, paths):
14     self._server = None
15     self._devnull = None
16     self._forwarder = None
17     self._host_port = util.GetAvailableLocalPort()
18
19     for path in paths:
20       assert os.path.exists(path), '%s does not exist.' % path
21     self._paths = set(map(os.path.realpath, paths))
22
23     common_prefix = os.path.commonprefix(self._paths)
24     if os.path.isdir(common_prefix):
25       self._base_dir = common_prefix
26     else:
27       self._base_dir = os.path.dirname(common_prefix)
28
29     self._devnull = open(os.devnull, 'w')
30     cmd = [sys.executable, '-m', 'memory_cache_http_server',
31            str(self._host_port)]
32     cmd.extend(self._paths)
33     env = os.environ.copy()
34     env['PYTHONPATH'] = os.path.abspath(os.path.dirname(__file__))
35     self._server = subprocess.Popen(cmd, cwd=self._base_dir,
36         env=env, stdout=self._devnull, stderr=self._devnull)
37
38     self._forwarder = browser_backend.CreateForwarder(
39         util.PortPair(self._host_port,
40                       browser_backend.GetRemotePort(self._host_port)))
41
42     def IsServerUp():
43       return not socket.socket().connect_ex(('localhost', self._host_port))
44     util.WaitFor(IsServerUp, 10)
45
46   @property
47   def paths(self):
48     return self._paths
49
50   def __enter__(self):
51     return self
52
53   def __exit__(self, *args):
54     self.Close()
55
56   def __del__(self):
57     self.Close()
58
59   def Close(self):
60     if self._forwarder:
61       self._forwarder.Close()
62       self._forwarder = None
63     if self._server:
64       self._server.kill()
65       self._server = None
66     if self._devnull:
67       self._devnull.close()
68       self._devnull = None
69
70   @property
71   def url(self):
72     return self._forwarder.url
73
74   def UrlOf(self, path):
75     relative_path = os.path.relpath(path, self._base_dir)
76     # Preserve trailing slash or backslash.
77     # It doesn't matter in a file path, but it does matter in a URL.
78     if path.endswith(os.sep) or (os.altsep and path.endswith(os.altsep)):
79       relative_path += '/'
80     return urlparse.urljoin(self.url, relative_path.replace(os.sep, '/'))