def server_run(self) : logging.info('Initializing socket ...') ip = config_parser.get_param(config_parser.CONFIG_IP) port = config_parser.get_param_int(config_parser.CONFIG_PORT) self.__master_sock = self.__init_socket(ip, port) logging.info('Creating worker threads ...') worker_num = config_parser.get_param_int(config_parser.CONFIG_WORKERS) if worker_num == None or worker_num <= 0 : worker_num = multiprocessing.cpu_count() for i in range(worker_num) : t = threading.Thread(target=self.__main_loop, args=(self.__master_sock,)) t.start() self.__workers.append(t) logging.info('Start thread no. {0}'.format(i))
def process_cgi(self) : tf_input = None tf_output = tempfile.mkstemp(prefix='tinyweb-cgi-') if os.fork() > 0 : # parent pass else : envdict = dict() envdict['DOCUMENT_ROOT'] = http_handler.web_root envdict['SCRIPT_FILENAME'] = self.local_file envdict['SCRIPT_NAME'] = os.path.basename(self.local_file) envdict['QUERY_STRING'] = self.query_str envdict['SERVER_NAME'] = config_parser.get_param(config_parser.CONFIG_SERVERNAME) envdict['SERVER_PORT'] = config_parser.get_param(config_parser.CONFIG_PORT) envdict['SERVER_SOFTWARE'] = tinyweb_common.TINYWEB_NAME + '/' + tinyweb_common.TINYWEB_VERSION envdict['HTTP_HOST'] = self.request_headers.get('Host') envdict['HTTP_USER_AGENT'] = self.request_headers.get('User-Agent') envdict['PATH'] = os.getenv('PATH') envdict['REQUEST_METHOD'] = self.request_method envdict['REQUEST_URI'] = self.request_url envdict['REMOTE_ADDR'] = self.io_event.address[0] envdict['REMOTE_PORT'] = str(self.io_event.address[1]) envdict['HTTP_REFERER'] = self.request_headers.get('Referer') # if it is a POST, we pass content-length env to child # and feed child with post data. if self.request_method == http_handler.request_method_post : logging.debug('set content_length env') envdict['CONTENT_LENGTH'] = str(self.post_content_length) tf_input = tempfile.TemporaryFile() # make sure to write all data to the file. num_w = 0 tries = 10 while (num_w < self.post_content_length) and (tries > 0) : try : num_w += tf_input.write(self.post_data[num_w:]) except IOError : tries -= 1 pass if tries <= 0 : logging.error('on POST, tried 10 times to write.') tf_input.seek(0) os.dup2(tf_input.fileno(), 0) # redirect stdout and stderr to temp file os.dup2(tf_output[0], 1) os.dup2(tf_output[0], 2) os.execve(self.local_file, [], envdict) exit(-1) # should never reach here pid, status = os.wait() # now set local_file in order to read the result self.local_file = tf_output[1] if tf_input : tf_input.close() # we don't need it any more. if status : logging.error('cgi child({0}) returned {1}'.format(pid, status))
#!/usr/bin/python3 import logging import tinycore from config_parser import config_parser from handler_factory import handler_factory if __name__ == '__main__' : logfile = config_parser.get_param(config_parser.CONFIG_LOG_FILE) loglevel = config_parser.get_param(config_parser.CONFIG_LOG_LEVEL) loglevel_dict = {'DEBUG' : logging.DEBUG, 'INFO' : logging.INFO, 'WARNING' : logging.WARNING, 'ERROR' : logging.ERROR, 'CRITICAL' : logging.CRITICAL} loglevel = loglevel_dict[loglevel] log_format = '[%(asctime)s] [%(levelname)8s]: %(message)s' logging.basicConfig(filename=logfile, level=loglevel, format=log_format) logging.info('Starting server ...') try : tc = tinycore.tinycore(handler_factory.HTTP) tc.server_run() tc.workers_join() except KeyboardInterrupt : logging.warning('KeyboardInterrupt catched') tc.terminate_workers_and_join() logging.info('Server stopped.') exit(0)