def __init__(self, *args): # unpack information about the request ''' (<supervisor.http.deferring_http_channel connected '' at 0x7fa350b44560 channel#: 1 requests:0>, u'POST /RPC2 HTTP/1.1', u'POST', u'/RPC2', u'1.1', [u'Host: localhost', u'Accept-Encoding: identity', u'Content-Length: 122', u'Content-Type: text/xml', u'Accept: text/xml', u'User-Agent: xmlrpclib.py/1.0.1 (by www.pythonware.com)']) :param args: ''' (self.channel, self.request, self.command, self.uri, self.version, self.header) = args self.outgoing = [] self.reply_headers = { 'Server': 'Medusa/%s' % VERSION_STRING, 'Date': http_date.build_http_date(time.time()) } # New reply header list (to support multiple # headers with same name) self.__reply_header_list = [] self.request_number = http_request.request_counter.increment() self._split_uri = None self._header_cache = {}
def handle_request(self, request): if request.command != 'GET': request.error (400) # bad request return path, params, query, fragment = request.split_uri() if '%' in path: path = http_server.unquote(path) # strip off all leading slashes while path and path[0] == '/': path = path[1:] path, process_name_and_channel = path.split('/', 1) try: process_name, channel = process_name_and_channel.split('/', 1) except ValueError: # no channel specified, default channel to stdout process_name = process_name_and_channel channel = 'stdout' from supervisor.options import split_namespec group_name, process_name = split_namespec(process_name) group = self.supervisord.process_groups.get(group_name) if group is None: request.error(404) # not found return process = group.processes.get(process_name) if process is None: request.error(404) # not found return logfile = getattr(process.config, '%s_logfile' % channel, None) if logfile is None or not os.path.exists(logfile): # we return 404 because no logfile is a temporary condition. # if the process has never been started, no logfile will exist # on disk. a logfile of None is also a temporay condition, # since the config file can be reloaded. request.error(404) # not found return mtime = os.stat(logfile)[stat.ST_MTIME] request['Last-Modified'] = http_date.build_http_date(mtime) request['Content-Type'] = 'text/plain;charset=utf-8' # the lack of a Content-Length header makes the outputter # send a 'Transfer-Encoding: chunked' response request['X-Accel-Buffering'] = 'no' # tell reverse proxy server (e.g., nginx) to disable proxy buffering # (see also http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering) request.push(tail_f_producer(request, logfile, 1024)) request.done()
def handle_request(self, request): if request.command != 'GET': request.error(400) # bad request return path, params, query, fragment = request.split_uri() if '%' in path: path = http_server.unquote(path) # strip off all leading slashes while path and path[0] == '/': path = path[1:] path, process_name_and_channel = path.split('/', 1) try: process_name, channel = process_name_and_channel.split('/', 1) except ValueError: # no channel specified, default channel to stdout process_name = process_name_and_channel channel = 'stdout' from supervisor.options import split_namespec group_name, process_name = split_namespec(process_name) group = self.supervisord.process_groups.get(group_name) if group is None: request.error(404) # not found return process = group.processes.get(process_name) if process is None: request.error(404) # not found return logfile = getattr(process.config, '%s_logfile' % channel, None) if logfile is None or not os.path.exists(logfile): # XXX problematic: processes that don't start won't have a log # file and we probably don't want to go into fatal state if we try # to read the log of a process that did not start. request.error(410) # gone return mtime = os.stat(logfile)[stat.ST_MTIME] request['Last-Modified'] = http_date.build_http_date(mtime) request['Content-Type'] = 'text/plain' # the lack of a Content-Length header makes the outputter # send a 'Transfer-Encoding: chunked' response request.push(tail_f_producer(request, logfile, 1024)) request.done()
def handle_request(self, request): if request.command != 'GET': request.error (400) # bad request return path, params, query, fragment = request.split_uri() if '%' in path: path = http_server.unquote(path) # strip off all leading slashes while path and path[0] == '/': path = path[1:] path, process_name_and_channel = path.split('/', 1) try: process_name, channel = process_name_and_channel.split('/', 1) except ValueError: # no channel specified, default channel to stdout process_name = process_name_and_channel channel = 'stdout' from supervisor.options import split_namespec group_name, process_name = split_namespec(process_name) group = self.supervisord.process_groups.get(group_name) if group is None: request.error(404) # not found return process = group.processes.get(process_name) if process is None: request.error(404) # not found return logfile = getattr(process.config, '%s_logfile' % channel, None) if logfile is None or not os.path.exists(logfile): # XXX problematic: processes that don't start won't have a log # file and we probably don't want to go into fatal state if we try # to read the log of a process that did not start. request.error(410) # gone return mtime = os.stat(logfile)[stat.ST_MTIME] request['Last-Modified'] = http_date.build_http_date(mtime) request['Content-Type'] = 'text/plain' # the lack of a Content-Length header makes the outputter # send a 'Transfer-Encoding: chunked' response request.push(tail_f_producer(request, logfile, 1024)) request.done()
def __init__(self, *args): # unpack information about the request (self.channel, self.request, self.command, self.uri, self.version, self.header) = args self.outgoing = [] self.reply_headers = {"Server": "Medusa/%s" % VERSION_STRING, "Date": http_date.build_http_date(time.time())} # New reply header list (to support multiple # headers with same name) self.__reply_header_list = [] self.request_number = http_request.request_counter.increment() self._split_uri = None self._header_cache = {}
def test_handle_request(self): supervisor = DummySupervisor() with tempfile.NamedTemporaryFile() as f: t = f.name supervisor.options.logfile = t handler = self._makeOne(supervisor) request = DummyRequest('/mainlogtail', None, None, None) handler.handle_request(request) self.assertEqual(request._error, None) from supervisor.medusa import http_date self.assertEqual(request.headers['Last-Modified'], http_date.build_http_date(os.stat(t)[stat.ST_MTIME])) self.assertEqual(request.headers['Content-Type'], 'text/plain') self.assertEqual(len(request.producers), 1) self.assertEqual(request._done, True)
def test_handle_request(self): supervisor = DummySupervisor() f = tempfile.NamedTemporaryFile() t = f.name supervisor.options.logfile = t handler = self._makeOne(supervisor) request = DummyRequest('/mainlogtail', None, None, None) handler.handle_request(request) self.assertEqual(request._error, None) from supervisor.medusa import http_date self.assertEqual(request.headers['Last-Modified'], http_date.build_http_date(os.stat(t)[stat.ST_MTIME])) self.assertEqual(request.headers['Content-Type'], 'text/plain') self.assertEqual(len(request.producers), 1) self.assertEqual(request._done, True)
def test_handle_request(self): f = tempfile.NamedTemporaryFile() t = f.name options = DummyOptions() pconfig = DummyPConfig(options, 'foo', 'foo', stdout_logfile=t) supervisord = PopulatedDummySupervisor(options, 'foo', pconfig) handler = self._makeOne(supervisord) request = DummyRequest('/logtail/foo', None, None, None) handler.handle_request(request) self.assertEqual(request._error, None) from supervisor.medusa import http_date self.assertEqual(request.headers['Last-Modified'], http_date.build_http_date(os.stat(t)[stat.ST_MTIME])) self.assertEqual(request.headers['Content-Type'], 'text/plain') self.assertEqual(len(request.producers), 1) self.assertEqual(request._done, True)
def test_handle_request(self): with tempfile.NamedTemporaryFile() as f: t = f.name options = DummyOptions() pconfig = DummyPConfig(options, 'foo', 'foo', stdout_logfile=t) supervisord = PopulatedDummySupervisor(options, 'foo', pconfig) handler = self._makeOne(supervisord) request = DummyRequest('/logtail/foo', None, None, None) handler.handle_request(request) self.assertEqual(request._error, None) from supervisor.medusa import http_date self.assertEqual(request.headers['Last-Modified'], http_date.build_http_date(os.stat(t)[stat.ST_MTIME])) self.assertEqual(request.headers['Content-Type'], 'text/plain') self.assertEqual(len(request.producers), 1) self.assertEqual(request._done, True)
def test_handle_request(self): supervisor = DummySupervisor() fd, tfilename = tempfile.mkstemp() try: supervisor.options.logfile = tfilename handler = self._makeOne(supervisor) request = DummyRequest('/mainlogtail', None, None, None) handler.handle_request(request) self.assertEqual(request._error, None) from supervisor.medusa import http_date self.assertEqual(request.headers['Last-Modified'], http_date.build_http_date(os.stat(tfilename)[stat.ST_MTIME])) self.assertEqual(request.headers['Content-Type'], 'text/plain') self.assertEqual(len(request.producers), 1) self.assertEqual(request._done, True) finally: os.close(fd)
def __init__(self, *args): # unpack information about the request (self.channel, self.request, self.command, self.uri, self.version, self.header) = args self.outgoing = [] self.reply_headers = { 'Server': 'Medusa/%s' % VERSION_STRING, 'Date': http_date.build_http_date(time.time()) } # New reply header list (to support multiple # headers with same name) self.__reply_header_list = [] self.request_number = http_request.request_counter.increment() self._split_uri = None self._header_cache = {}
def handle_request(self, request): if request.command != 'GET': request.error(400) # bad request return logfile = self.supervisord.options.logfile if logfile is None or not os.path.exists(logfile): request.error(410) # gone return mtime = os.stat(logfile)[stat.ST_MTIME] request['Last-Modified'] = http_date.build_http_date(mtime) request['Content-Type'] = 'text/plain' # the lack of a Content-Length header makes the outputter # send a 'Transfer-Encoding: chunked' response request.push(tail_f_producer(request, logfile, 1024)) request.done()
def handle_request(self, request): if request.command != 'GET': request.error (400) # bad request return logfile = self.supervisord.options.logfile if logfile is None or not os.path.exists(logfile): request.error(410) # gone return mtime = os.stat(logfile)[stat.ST_MTIME] request['Last-Modified'] = http_date.build_http_date(mtime) request['Content-Type'] = 'text/plain' # the lack of a Content-Length header makes the outputter # send a 'Transfer-Encoding: chunked' response request.push(tail_f_producer(request, logfile, 1024)) request.done()
def handle_request(self, request): if request.command != 'GET': request.error (400) # bad request return logfile = self.supervisord.options.logfile if logfile is None or not os.path.exists(logfile): # we return 404 because no logfile is a temporary condition. # even if a log file of None is configured, the config file # may be reloaded, and the new config may have a logfile. request.error(404) # not found return mtime = os.stat(logfile)[stat.ST_MTIME] request['Last-Modified'] = http_date.build_http_date(mtime) request['Content-Type'] = 'text/plain;charset=utf-8' # the lack of a Content-Length header makes the outputter # send a 'Transfer-Encoding: chunked' response request.push(tail_f_producer(request, logfile, 1024)) request.done()
# -*- Mode: Python -*- import supervisor.medusa.text_socket as socket import time from supervisor.medusa import http_date now = http_date.build_http_date (time.time()) cache_request = '\r\n'.join( ['GET / HTTP/1.0', 'If-Modified-Since: %s' % now, ]) + '\r\n\r\n' nocache_request = 'GET / HTTP/1.0\r\n\r\n' def get (request, host='', port=8080): s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.send(request) while 1: d = s.recv (8192) if not d: break s.close() class timer: def __init__ (self): self.start = time.time() def end (self): return time.time() - self.start
def handle_request(self, request): if request.command not in self.valid_commands: request.error(400) # bad request return self.hit_counter.increment() path, params, query, fragment = request.split_uri() if '%' in path: path = unquote(path) # strip off all leading slashes while path and path[0] == '/': path = path[1:] if self.filesystem.isdir(path): if path and path[-1] != '/': request['Location'] = 'http://%s/%s/' % ( request.channel.server.server_name, path ) request.error(301) return # we could also generate a directory listing here, # may want to move this into another method for that # purpose found = 0 if path and path[-1] != '/': path += '/' for default in self.directory_defaults: p = path + default if self.filesystem.isfile(p): path = p found = 1 break if not found: request.error(404) # Not Found return elif not self.filesystem.isfile(path): request.error(404) # Not Found return file_length = self.filesystem.stat(path)[stat.ST_SIZE] ims = get_header_match(IF_MODIFIED_SINCE, request.header) length_match = 1 if ims: length = ims.group(4) if length: try: length = int(length) if length != file_length: length_match = 0 except: pass ims_date = 0 if ims: ims_date = http_date.parse_http_date(ims.group(1)) try: mtime = self.filesystem.stat(path)[stat.ST_MTIME] except: request.error(404) return if length_match and ims_date: if mtime <= ims_date: request.reply_code = 304 request.done() self.cache_counter.increment() return try: file = self.filesystem.open(path, 'rb') except IOError: request.error(404) return request['Last-Modified'] = http_date.build_http_date(mtime) request['Content-Length'] = file_length self.set_content_type(path, request) if request.command == 'GET': request.push(self.default_file_producer(file)) self.file_counter.increment() request.done()
def handle_request (self, request): if request.command not in self.valid_commands: request.error (400) # bad request return self.hit_counter.increment() path, params, query, fragment = request.split_uri() if '%' in path: path = unquote (path) # strip off all leading slashes while path and path[0] == '/': path = path[1:] if self.filesystem.isdir (path): if path and path[-1] != '/': request['Location'] = 'http://%s/%s/' % ( request.channel.server.server_name, path ) request.error (301) return # we could also generate a directory listing here, # may want to move this into another method for that # purpose found = 0 if path and path[-1] != '/': path += '/' for default in self.directory_defaults: p = path + default if self.filesystem.isfile (p): path = p found = 1 break if not found: request.error (404) # Not Found return elif not self.filesystem.isfile (path): request.error (404) # Not Found return file_length = self.filesystem.stat (path)[stat.ST_SIZE] ims = get_header_match (IF_MODIFIED_SINCE, request.header) length_match = 1 if ims: length = ims.group (4) if length: try: length = int(length) if length != file_length: length_match = 0 except: pass ims_date = 0 if ims: ims_date = http_date.parse_http_date (ims.group (1)) try: mtime = self.filesystem.stat (path)[stat.ST_MTIME] except: request.error (404) return if length_match and ims_date: if mtime <= ims_date: request.reply_code = 304 request.done() self.cache_counter.increment() return try: file = self.filesystem.open (path, 'rb') except IOError: request.error (404) return request['Last-Modified'] = http_date.build_http_date (mtime) request['Content-Length'] = file_length self.set_content_type (path, request) if request.command == 'GET': request.push (self.default_file_producer (file)) self.file_counter.increment() request.done()
# -*- Mode: Python -*- import socket import string import time from supervisor.medusa import http_date now = http_date.build_http_date(time.time()) cache_request = string.joinfields([ 'GET / HTTP/1.0', 'If-Modified-Since: %s' % now, ], '\r\n') + '\r\n\r\n' nocache_request = 'GET / HTTP/1.0\r\n\r\n' def get(request, host='', port=80): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.send(request) while 1: d = s.recv(8192) if not d: break s.close() class timer: def __init__(self): self.start = time.time()