def serve_client(self, client, req: Request): try: Logger.debug_info(f'Request {req}') if req.insufficient(): raise Errors.MALFORMED_REQ a = time.perf_counter() res = self.handle_req(req) Logger.debug_info( f'Request handling time {time.perf_counter() - a}') Logger.debug_info(f'Response prepared {res}') Response.send_response(client, res) Logger.debug_info(f'Response sent') Logger.info(f'Source Requested', extra={ 'method': req.method, 'url': req.path, 'code': res.status, 'ip': client.getpeername() }) if req.headers.get('Connection') == 'keep-alive': client.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) if req.headers.get('Connection') == 'close': self.close(client) except KeepAliveExpire: self.close(client) except Exception as e: Logger.exception(f'Client handling failed') send_error(client, e, self.configurator)
def show(req: Request, server): res = Response.build_file_res(req, os.path.join(ROOT_DIR, 'tmp', 'upload.html'), 'text/html') dir_list = os.listdir(os.path.join(ROOT_DIR, "tmp", "saved")) body = f'{json.dumps(dir_list)}'.encode() headers = [ ('Content-Type', f'application/json'), ('Content-Disposition', f'inline; filename=Echo query'), ('Content-Length', len(body)), ] return Response(200, 'OK', headers, body)
def handle(req: Request, server: Server): if req.path.startswith('/') and req.method == 'GET': rules = server.configurator._get_rules() path = urllib.parse.unquote(req.path) res = server.cache.get(path) if res: Logger.debug_info(f'Cache found for {path}') return res page = server.router.find_page_description(path, rules) destination = server.router.get_destination(path, rules, True) content_type = page.get_mime() if destination: if not content_type: mime = magic.Magic(mime=True) content_type = mime.from_file(destination) server.cache.close() res = Response.build_file_res(req, destination, content_type, add_headers=page.get_headers()) if int(res.status) == 200: Logger.debug_info(f'Updating cache for {path}') server.cache.set(path, res, expire=EXPIRE, tag='data') server.cache.cull() return res raise Errors.NOT_FOUND
def load(req: Request, server): filename = re.sub('/load/', '', req.target) destination = os.path.join(ROOT_DIR, "tmp", "saved", urllib.parse.unquote(filename)) content_type = magic.Magic(mime=True).from_file(destination) res = Response.build_file_res(req, destination, content_type) return res
def get_posts(req: Request, server): body = f'{json.dumps(POSTS)}'.encode() headers = [ ('Content-Type', f'application/json'), ('Content-Disposition', f'inline; filename=Get posts'), ('Content-Length', len(body)), ] return Response(200, 'OK', headers, body)
def send_error(connection, err, config): try: if err.page: with open(config.get("error-pages").get(err.page), 'rb') as p: p = p.read() res = [Response.build_err_res(err.status, err.reason, p)] else: res = [ Response.build_err_res(err.status, err.reason, (err.body or err.reason).encode('utf-8')) ] except Exception as e: Logger.error(f'Error during err creation', e) res = [ Response.build_err_res(500, b'Internal Server Error', b'Internal Server Error') ] Response.send_response(connection, *res)
def save(req: Request, server): h = re.compile( b'-+?.+?\r\n' b'Content-Disposition: form-data; ' b'name=\"(?P<name>.*?)\"; ' b'filename=\"(?P<filename>.*?)\"\r\n' b'.+?: (?P<ct>.+?)\r\n' b'\r\n', re.S) tail_pos = 3 while True: req.body_file.seek(-tail_pos, 2) tail = req.body_file.tell() t = req.body_file.read(tail_pos) if t.startswith(b'\r\n'): break tail_pos += 1 head_crlf_count = 4 head = b'' req.body_file.seek(0) i = 0 while True: if i == head_crlf_count: break head += req.body_file.read(1) if head.endswith(b'\r\n'): i += 1 data_start = req.body_file.tell() match = h.search(head) if not match: raise Errors.MALFORMED_REQ groups = match.groupdict() ftype = groups.get('name') fname = Request.decode(groups.get('filename')) if fname: with open(os.path.join(ROOT_DIR, 'tmp', 'saved', fname), 'wb') as f: f.write(req.body_file.read(tail - data_start)) Logger.debug_info(f'{ftype} saved as {fname} ') body = f'{os.path.join(ROOT_DIR, "tmp", "saved")}' \ f' - >' \ f' {os.listdir(os.path.join(ROOT_DIR, "tmp", "saved"))}' else: body = 'Empty file' headers = [ ('Content-Type', f'application/json'), ('Content-Disposition', f'inline; filename=Echo query'), ('Content-Length', len(body)), ('Location', '/upload'), ] return Response(301, 'Moved Permanently', headers, body.encode())
def img(req: Request, server): with open('/schema.jpg', 'rb') as f: to_send = f.read() body = to_send headers = [ ('Content-Type', f'application/json'), ('Content-Disposition', f'inline; filename=Get posts'), ('Content-Length', len(body)), ("Access-Control-Allow-Origin", '*') ] return Response(200, 'OK', headers, body)
def get(req: Request, server): cb_name = req.query['callback'][0] to_send = f'{cb_name}({json.dumps(TO_SEND)});' body = f'{to_send}'.encode() headers = [ ('Content-Type', f'application/json'), ('Content-Disposition', f'inline; filename=Get posts'), ('Content-Length', len(body)), ("Access-Control-Allow-Origin", '*') ] return Response(200, 'OK', headers, body)
def handle_post(req: Request, server): req.body_file.seek(0) body = req.body_file.read() body = Request.decode(body) query = parse_qs(f'{body}') POSTS.append(query) body = f'POST ADDED {query}'.encode() headers = [ ('Content-Type', f'application/json'), ('Content-Disposition', f'inline; filename=Post'), ('Content-Length', len(body)), ('Location', '/my_guest_book'), ] return Response(301, 'Moved Permanently', headers, body)
def post(req: Request, server): Logger.debug_info(f'POST---------') req.body_file.seek(0) body = req.body_file.read() body = Request.decode(body) Logger.debug_info(f'POSTED -> {body}') post_data = json.loads(body) BOOKS.append({ 'id': uuid.uuid4().hex, 'title': post_data.get('title'), 'author': post_data.get('author'), 'read': post_data.get('read') }) SUCCESS['message'] = 'Books added!' body = f'{json.dumps(SUCCESS)}'.encode() headers = [ ('Content-Type', f'application/json'), ('Content-Disposition', f'inline; filename=Get posts'), ('Content-Length', len(body)), ("Access-Control-Allow-Origin", '*') ] return Response(200, 'OK', headers, body)
def func(req, srv): return Response('OK', 200)