예제 #1
0
    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)
예제 #2
0
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)
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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)
예제 #6
0
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)
예제 #7
0
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())
예제 #8
0
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)
예제 #9
0
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)
예제 #10
0
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)
예제 #11
0
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)