Ejemplo n.º 1
0
def test_login(app_url, uuid):
    r = requests.post(app_url + '/phone/send', json={'phone': '+380711234567'})
    assert r.ok
    otp_id = r.json()['verification_id']

    otps = requests.get(
        'https://twilio/2010-04-01/Accounts/123456/Messages.json',
        verify=False)
    otp = otps.json()[0]['Body']
    print(otp)
    r = requests.post(app_url + '/phone/login',
                      json={
                          'otp_id': otp_id,
                          'otp': otp
                      })
    assert r.ok
    assert r.headers['access'] is not None
    assert r.headers['Set-Cookie'] is not None

    cookie = SimpleCookie()
    cookie.load(r.headers['Set-Cookie'])
    assert cookie.get('refresh_token') is not None
    assert verify_jwt(r.headers['access'],
                      cookie.get('refresh_token').value,
                      BASE_URL + '/phone-pwless-jwk-file/jwk', ['RS256'], uuid,
                      'Aureole Server')

    requests.delete('https://twilio/2010-04-01/Accounts/123456/Messages.json',
                    verify=False)
Ejemplo n.º 2
0
def test_login(app_url, uuid):
    login_resp = requests.post(app_url + '/login',
                               json={
                                   'email': '*****@*****.**',
                                   'password': '******'
                               })
    assert login_resp.ok
    assert login_resp.headers['access'] is not None

    cookie = SimpleCookie()
    cookie.load(login_resp.headers['Set-Cookie'])
    assert cookie.get('refresh_token') is not None
    assert verify_jwt(login_resp.headers['access'],
                      cookie.get('refresh_token').value,
                      app_url + '/gen-keys/jwk', ['ES256'], uuid,
                      'Aureole Server')

    refresh_resp = requests.post(app_url + '/refresh',
                                 cookies=login_resp.cookies)
    assert refresh_resp.ok
    assert refresh_resp.headers['access'] is not None
    assert verify_jwt(refresh_resp.headers['access'],
                      cookie.get('refresh_token').value,
                      app_url + '/gen-keys/jwk', ['ES256'], uuid,
                      'Aureole Server')
Ejemplo n.º 3
0
def test_facebook_login(app_url, uuid):
    r = requests.get(app_url + '/oauth2/facebook', verify=False)
    print(r.text)
    assert r.ok
    assert r.headers['access'] is not None

    cookie = SimpleCookie()
    cookie.load(r.headers['Set-Cookie'])
    assert cookie.get('refresh_token') is not None
    assert verify_jwt(r.headers['access'],
                      cookie.get('refresh_token').value,
                      app_url + '/social-auth-jwk-file/jwk', ['RS256'], uuid,
                      'Aureole Server')
Ejemplo n.º 4
0
    def do_CONNECT(self, initial_data):
        print("In do_Connect")
        global secret_key
        global pamenabled
        cookies = SimpleCookie(self.headers.get('Cookie'))

        path = self.path

        if pamenabled == True:
            try:
                cookie = cookies.get("p_auth").value
                clientip = self.client_address[0]
                if clientip == "127.0.0.1":
                    if not self.headers.get("x-forwarded-for") == "":
                        clientip = self.headers.get("x-forwarded-for")

                result = validateCookie(secret_key, cookie, clientip)
            except:
                result = False

            if result == False:
                self.send_response(302)
                self.send_header("Location", "/authentication_services")
                self.end_headers()
                return None

            temp = "CONNECT " + self.path + " " + "HTTP/1.1\r\n"
            cookie = cookies.get("p_auth").value
            data = cookie.split("username="******"&")[0]
        else:
            username = "******"

        for x in self.headers:
            if x.lower() == "remote_user":
                print("Skipping " + x.lower())
            elif x.lower() == "cookie":
                cookietemp = self.headers.get(x).split("=")[0]
                if cookietemp.lower() == "p_auth":
                    print("Skipping " + x.lower())
                else:
                    temp = temp + x + ": " + self.headers.get(x) + "\r\n"
            else:
                temp = temp + x + ": " + self.headers.get(x) + "\r\n"
        temp = temp + "remote_user: "******"\r\n\r\n"
        #print(temp)

        self.dataConnectorCONNECT(0, temp, remotehost, int(remoteport))
Ejemplo n.º 5
0
def parse_cookie(name, seed, kaka):
    """Parses and verifies a cookie value

    :param seed: A seed used for the HMAC signature
    :param kaka: The cookie
    :return: A tuple consisting of (payload, timestamp)
    """
    if not kaka:
        return None

    cookie_obj = SimpleCookie(kaka)
    morsel = cookie_obj.get(name)

    if morsel:
        parts = morsel.value.split("|")
        if len(parts) != 3:
            return None
            # verify the cookie signature
        sig = cookie_signature(seed, parts[0], parts[1])
        if sig != parts[2]:
            raise SAMLError("Invalid cookie signature")

        try:
            return parts[0].strip(), parts[1]
        except KeyError:
            return None
    else:
        return None
Ejemplo n.º 6
0
    def getSession(self):
        """Return the existing session or a new session"""
        if self.session is not None:
            return self.session

        # Get value of cookie header that was sent
        cookie_str = self.headers.get('Cookie')
        if cookie_str:
            cookie_obj = SimpleCookie(cookie_str)
            sid_morsel = cookie_obj.get(self.SESSION_COOKIE_NAME, None)
            if sid_morsel is not None:
                sid = sid_morsel.value
            else:
                sid = None
        else:
            sid = None

        # If a session id was not set, create a new one
        if sid is None:
            sid = randomString(16, '0123456789abcdef')
            session = None
        else:
            session = self.server.sessions.get(sid)

        # If no session exists for this session ID, create one
        if session is None:
            session = self.server.sessions[sid] = {}

        session['id'] = sid
        self.session = session
        return session
Ejemplo n.º 7
0
    def __init__(self, path, query_string, cookie, method, post, url_scheme,
                 host):

        self._routes = dict()
        self.pattern_url = ""
        self.path = path
        self.full_path = path
        self.query_string = query_string
        self.method = method
        self.post = post
        self.url_scheme = url_scheme
        self.host = host
        self.matchdict = {}

        self.reinit()
        if settings.SQLITE_DBNAME:
            self.db = db.Database(settings.SQLITE_DBNAME)
            if cookie:
                request_cookie = SimpleCookie(cookie)
                if request_cookie.get("session"):
                    session_id = request_cookie["session"].value
                    if session_id:
                        self.session_id = session_id
            if not self.session_id:
                self.session_id = uuid.uuid4().hex
                self.db.insert_session(self.session_id)
            session = self.db.get_session(self.session_id)
            self.session, self.session_expires = session
            if self.session_expires > datetime.datetime.utcnow().replace(
                    tzinfo=datetime.timezone.utc) - timedelta(days=1):
                cookie = SimpleCookie()
                cookie["session"] = self.session_id
                cookie["session"]["expires"] = settings.SESSION_LENGTH
                self.set_cookie = tuple(cookie.output().split(": ", 1))
            self.user = self.db.get_user_by_session(self.session_id)
Ejemplo n.º 8
0
def upload(env, start_response):
    form = cgi.FieldStorage(fp=env['wsgi.input'],
                            environ=env,
                            keep_blank_values=True)
    image = form['image'].value
    HTTP_COOKIE = env.get('HTTP_COOKIE', '')
    cookie = SimpleCookie(HTTP_COOKIE)

    username = cookie.get('username').value

    file_type = os.path.splitext(form['image'].filename)[-1]
    file_name = getDigest(username)

    path = '/home/ubuntu/sources/demo0/images/' + file_name + file_type
    f = open(path, mode='wb+')
    f.write(image)

    db = getDBConn('test_db')
    cursor = db.cursor()
    sql = "UPDATE user_db SET profile_image=%s WHERE username=%s;"
    cursor.execute(sql, [file_name + file_type, username])
    db.commit()
    db.close()
    image_url = image_url_prefix + file_name + file_type

    start_response('200 OK', [('Content-type', 'text/html')])
    return getTemplate('yagra/profile.html')\
           .render(image = image_url,
             tag = False,
             username = username)\
           .encode('utf-8')
Ejemplo n.º 9
0
def parse_cookie(name, seed, kaka):
    """Parses and verifies a cookie value

    :param seed: A seed used for the HMAC signature
    :param kaka: The cookie
    :return: A tuple consisting of (payload, timestamp)
    """
    if not kaka:
        return None

    cookie_obj = SimpleCookie(kaka)
    morsel = cookie_obj.get(name)

    if morsel:
        parts = morsel.value.split("|")
        if len(parts) != 3:
            return None
            # verify the cookie signature
        sig = cookie_signature(seed, parts[0], parts[1])
        if sig != parts[2]:
            raise SAMLError("Invalid cookie signature")

        try:
            return parts[0].strip(), parts[1]
        except KeyError:
            return None
    else:
        return None
Ejemplo n.º 10
0
    def getSession(self):
        """Return the existing session or a new session"""
        if self.session is not None:
            return self.session

        # Get value of cookie header that was sent
        cookie_str = self.headers.get('Cookie')
        if cookie_str:
            cookie_obj = SimpleCookie(cookie_str)
            sid_morsel = cookie_obj.get(self.SESSION_COOKIE_NAME, None)
            if sid_morsel is not None:
                sid = sid_morsel.value
            else:
                sid = None
        else:
            sid = None

        # If a session id was not set, create a new one
        if sid is None:
            sid = randomString(16, '0123456789abcdef')
            session = None
        else:
            session = self.server.sessions.get(sid)

        # If no session exists for this session ID, create one
        if session is None:
            session = self.server.sessions[sid] = {}

        session['id'] = sid
        self.session = session
        return session
Ejemplo n.º 11
0
def cookie_parts(name, kaka):
    cookie_obj = SimpleCookie(text_type(kaka))
    morsel = cookie_obj.get(name)
    if morsel:
        return morsel.value.split("|")
    else:
        return None
Ejemplo n.º 12
0
def cookie_parts(name, kaka):
    cookie_obj = SimpleCookie(kaka)
    morsel = cookie_obj.get(name)
    if morsel:
        return morsel.value.split("|")
    else:
        return None
Ejemplo n.º 13
0
    def get_cookie(self, key):
        cookie_string = self.req_env.get('HTTP_COOKIE', None)
        if cookie_string is None:
            return

        cookie = SimpleCookie()
        cookie.load(cookie_string)

        return cookie.get(key, None).value
Ejemplo n.º 14
0
    def _initialize_consent(self):
        """
        Set a consent cookie if not yet present in the cookie jar, and in the
        request headers as a result.
        If a pending consent cookie is there, accept it to avoid the blocking page.
        """
        # Make a first request to get initial cookies, in case none were passed
        # as argument (or failed to load)
        # TODO perhaps this needs to be done once in a while for very long
        # running sessions.
        req = Request('https://www.youtube.com/', headers=self.headers)

        cookies = SimpleCookie(req.get_header('Cookie'))
        if cookies.get('__Secure-3PSID'):
            return
        consent_id = None
        consent = cookies.get('CONSENT')
        if consent:
            if 'YES' in consent.value:
                return
            consent_id = re.search(r'PENDING\+(\d+)', consent.value)
        if not consent_id:
            consent_id = randint(100, 999)
        domain = '.youtube.com'
        cookie = Cookie(
            0,  # version
            'CONSENT',  # name
            'YES+cb.20210328-17-p0.en+F+%s' % consent_id,  # value
            None,  # port
            False,  # port_specified
            domain,  # domain
            True,  # domain_specified
            domain.startswith('.'),  # domain_initial_dot
            '/',  # path
            True,  # path_specified
            False,  # secure
            None,  # expires
            False,  # discard
            None,  # comment
            None,  # comment_url
            {}  # rest
        )

        self.cookie_jar.set_cookie(cookie)
Ejemplo n.º 15
0
def cookie_parts(name, kaka):
    if not isinstance(kaka, SimpleCookie):
        cookie_obj = SimpleCookie(str(kaka))
    else:
        cookie_obj = kaka
    morsel = cookie_obj.get(name)
    if morsel:
        return morsel.value.split("|")
    else:
        return None
Ejemplo n.º 16
0
    def onConnect(self, request):
        from http.cookies import SimpleCookie
        s = SimpleCookie(request.headers["cookie"])
        val = s.get(app.session_cookie_name).value
        self.cookies = {app.session_cookie_name: val}
        ss = seFactory.open_session(app, self)

        print(ss.get("test"))
        print(request.params)
        return None
Ejemplo n.º 17
0
 def get_sid():
     """
     Returns the real SID value
     """
     cookie = SimpleCookie()
     cookie_string = environ.get('HTTP_COOKIE', '')
     cookie.load(cookie_string)
     sid = 0 if not SessionAnomalyChecker.is_not_sid else cookie.get('__PYSESSION__SID')
     sid = cookie['__PYSESSION__SID'].value if '__PYSESSION__SID' in cookie else '0'
     return SessionsHelper.clear(sid)
Ejemplo n.º 18
0
 def _loadSessionFromCookie(self, environ):
     """
     Attempt to load the associated session using the identifier from
     the cookie.
     """
     C = SimpleCookie(environ.get('HTTP_COOKIE'))
     morsel = C.get(self._cookieName, None)
     if morsel is not None:
         self._session = self._store.checkOutSession(morsel.value)
         self._expired = self._session is None
Ejemplo n.º 19
0
def cookie_parts(name, kaka):
    if not isinstance(kaka, SimpleCookie):
        cookie_obj = SimpleCookie(str(kaka))
    else:
        cookie_obj = kaka
    morsel = cookie_obj.get(name)
    if morsel:
        return morsel.value.split("|")
    else:
        return None
Ejemplo n.º 20
0
    def __call__(self, req):
        cookie = req.headers.get('HTTP_COOKIE')
        action = req.GET_params.get('action')

        session_token = None

        if cookie:
            parsed_cookie = SimpleCookie(cookie)
            session_token = parsed_cookie.get('session')

            if action and action == 'logout':
                # Because particular session id was removed - next
                # condition won't trigger and we wil be redirected to
                # home in logout state, previous session id cookie will
                # not be valid
                if session_token and session_token.value in self.sessions:
                    self.sessions.remove(session_token.value)

        with FlashManager() as f_mng:
            # logged-in state
            if session_token and session_token.value in self.sessions:
                requested_path = req.GET_params.get('path')
                create_dir_action = req.POST_params.get('dir_name_create')
                cur_client = self.current_users[session_token.value]

                # path wants to be deleted
                if requested_path and action:
                    self.handle_remove(requested_path, action,
                                       cur_client, f_mng)

                # if make dir required
                elif create_dir_action:
                    pseudo_dir_name = create_dir_action[0]
                    self.handle_make_dir(pseudo_dir_name, cur_client, f_mng)

                # if upload required
                elif req.file:
                    self.handle_upload_file(cur_client, req, f_mng)

                # if some path requested in query string and no
                # specific action requested
                elif requested_path and not action:
                    # requested path - file
                    if self.is_file(cur_client.u_name, requested_path):
                        return self.handle_download_file(cur_client.u_name,
                                                         requested_path)
                    # requested path - directory
                    else:
                        cur_client.cwd = requested_path

                dir_view = cur_client.get_dir_view()
                return render_template('main.html', dir_view=dir_view,
                                       flash_messages=f_mng.get_flashes())

        return self.app.redirect(self.app.url_for(req, '/'))
def test_set_cookie(clean_manager, default_data):
    token = clean_manager.create_access_token(data=default_data)
    response = Response()
    clean_manager.set_cookie(response, token)
    cookie = SimpleCookie(response.headers['set-cookie'])
    cookie_value = cookie.get(clean_manager.cookie_name)
    assert cookie_value is not None
    assert cookie_value["httponly"] is True
    assert cookie_value["samesite"] == "lax"
    assert cookie_value.value == token
    assert cookie_value.key == clean_manager.cookie_name
Ejemplo n.º 22
0
    def __call__(self, req):
        cookie = req.headers.get('HTTP_COOKIE')
        if cookie:
            parsed_cookie = SimpleCookie(cookie)
            session_token = parsed_cookie.get('session')

            if session_token and session_token.value in self.sessions:
                return self.app.redirect(
                    self.app.url_for(req, 'main')
                )

        return render_template('index.html')
Ejemplo n.º 23
0
def test_login(app_url, uuid):
    r = requests.post(app_url + '/email-link/send',
                      json={'email': '*****@*****.**'})
    assert r.ok

    emails = requests.get('http://smtp:1080/api/emails')
    link = emails.json()[0]['text']
    r = requests.get(link)
    assert r.ok
    assert r.headers['access'] is not None
    assert r.headers['Set-Cookie'] is not None

    cookie = SimpleCookie()
    cookie.load(r.headers['Set-Cookie'])
    assert cookie.get('refresh_token') is not None
    assert verify_jwt(r.headers['access'],
                      cookie.get('refresh_token').value,
                      BASE_URL + '/email-pwless-jwk-file/jwk', ['RS256'], uuid,
                      'Aureole Server')

    requests.delete('http://smtp:1080/api/emails')
Ejemplo n.º 24
0
 def kaka2user(self, kaka):
     logger.debug("KAKA: %s" % kaka)
     if kaka:
         cookie_obj = SimpleCookie(kaka)
         morsel = cookie_obj.get(self.cookie_name, None)
         if morsel:
             try:
                 return self.uid2user[morsel.value]
             except KeyError:
                 return None
         else:
             logger.debug("No spauthn cookie")
     return None
Ejemplo n.º 25
0
def delete_cookie(environ, name):
    kaka = environ.get("HTTP_COOKIE", '')
    logger.debug("delete KAKA: %s" % kaka)
    if kaka:
        cookie_obj = SimpleCookie(kaka)
        morsel = cookie_obj.get(name, None)
        cookie = SimpleCookie()
        cookie[name] = ""
        cookie[name]['path'] = "/"
        logger.debug("Expire: %s" % morsel)
        cookie[name]["expires"] = _expiration("dawn")
        return tuple(cookie.output().split(": ", 1))
    return None
Ejemplo n.º 26
0
    def get_session_id(self, headers):
        cookie_header = headers.get('cookie')
        if not cookie_header:
            return None

        cookie = SimpleCookie()
        cookie.load(cookie_header)

        session_id_cookie = cookie.get(SESSION_COOKIE_NAME)
        if not session_id_cookie:
            return None

        return session_id_cookie.value
Ejemplo n.º 27
0
def delete_cookie(environ, name):
    kaka = environ.get("HTTP_COOKIE", '')
    logger.debug("delete KAKA: %s" % kaka)
    if kaka:
        cookie_obj = SimpleCookie(kaka)
        morsel = cookie_obj.get(name, None)
        cookie = SimpleCookie()
        cookie[name] = ""
        cookie[name]['path'] = "/"
        logger.debug("Expire: %s" % morsel)
        cookie[name]["expires"] = _expiration("dawn")
        return tuple(cookie.output().split(": ", 1))
    return None
Ejemplo n.º 28
0
 def kaka2user(self, kaka):
     logger.debug("KAKA: %s" % kaka)
     if kaka:
         cookie_obj = SimpleCookie(kaka)
         morsel = cookie_obj.get(self.cookie_name, None)
         if morsel:
             try:
                 return self.uid2user[morsel.value]
             except KeyError:
                 return None
         else:
             logger.debug("No spauthn cookie")
     return None
Ejemplo n.º 29
0
def parse_cookie(cookie):
    if cookie == '':
        return {}
    try:
        c = SimpleCookie()
        c.load(cookie)
    except CookieError:
        # Invalid cookie
        return {}

    cookiedict = {}
    for key in list(c.keys()):
        cookiedict[key] = c.get(key).value
    return cookiedict
Ejemplo n.º 30
0
def info_from_cookie(kaka):
    logger.debug("KAKA: %s" % kaka)
    if kaka:
        cookie_obj = SimpleCookie(kaka)
        morsel = cookie_obj.get("idpauthn", None)
        if morsel:
            try:
                key, ref = base64.b64decode(morsel.value).split(":")
                return IDP.cache.uid2user[key], ref
            except KeyError:
                return None, None
        else:
            logger.debug("No idpauthn cookie")
    return None, None
Ejemplo n.º 31
0
class Request:
    NONE_COOKIE = object()
    def __init__(self, HTTPRequest: BaseHTTPRequestHandler):
        self.req = HTTPRequest
        self.path = self.req.path
        self.headers = self.req.headers
        self.server = self.req.server
        self.addr = self.req.client_address
        self.type = self.req.command
        self.cookie = SimpleCookie()

        # Generate cookies
        c = self.get_header('Cookie')
        if c is not None:
            self.cookie.load(c)

        # Search for GET query
        self.get_query = None
        q = self.path.split('?')
        if len(q) > 1:
            self.get_query = parse_qs(q[1])
        self.path = q[0]

        # Generate POST vals
        self.post_vals = None
        if self.type == 'POST':
            content_len = int(self.get_header('content-length'))
            post_body = self.req.rfile.read(content_len)
            self.post_vals = parse_qs(post_body.decode(ENCODING))

        # Generate client object (now done in handlers.py)
        # self.client = client.ClientObj(self.addr[0], self.get_cookie('user_token'))

    def get_header(self, key):
        return self.headers.get(key.lower())

    def get_cookie(self, key):
        v = self.cookie.get(key, Morsel()).value
        return None if v is '_none' else v

    def get_post(self, key):
        v = self.post_vals.get(key)
        if v is None:
            return
        if len(v) == 1:
            return v[0]
        return v

    def read(self):
        return self.req.rfile.read()
Ejemplo n.º 32
0
def info_from_cookie(kaka):
    logger.debug("KAKA: %s" % kaka)
    if kaka:
        cookie_obj = SimpleCookie(kaka)
        morsel = cookie_obj.get("idpauthn", None)
        if morsel:
            try:
                key, ref = base64.b64decode(morsel.value).split(":")
                return IDP.cache.uid2user[key], ref
            except KeyError:
                return None, None
        else:
            logger.debug("No idpauthn cookie")
    return None, None
Ejemplo n.º 33
0
def oauth2_code(event, context):

    token_url = f"{api_url}/tradeshift/auth/token"

    print(event)

    oauth_state = ''

    headers = event.get('headers', {})
    cookie = SimpleCookie()
    cookie.load(rawdata=headers.get('Cookie', ''))

    requestContext = event.get('requestContext')
    path = requestContext.get('path')
    domain_name = requestContext.get('domainName')
    callback_url = f"https://{domain_name}{path}"

    code = event.get('queryStringParameters', {}).get('code', '')

    if SESSION_COOKIE_KEY in cookie:
        key = cookie.get(SESSION_COOKIE_KEY).value
        saved_session = engine.get(SessionObject, key=key)
        oauth_state = saved_session.state

    tradeshift = f(client_id, state=oauth_state)

    print(f"code: {code}")
    print(f"oauth_state: {oauth_state}")
    print(f"callback_url: {callback_url}")
    print(f"token_url: {token_url}")

    auth = HTTPBasicAuth(client_id, client_secret)
    client = BackendApplicationClient(client_id=client_id)
    tradeshift = OAuth2Session(client=client)
    token = tradeshift.fetch_token(token_url=token_url, code=code, auth=auth)

    # https://ef0ymjxyc8.execute-api.eu-west-1.amazonaws.com/dev/oauth2/callback/
    # token = tradeshift.fetch_token(token_url, authorization_response=callback_url, client_secret=client_secret, headers=authorization_header) #, include_client_id=True, client_id=client_i<d<)

    body = {
        "message": "oauth2_code called",
        "input": event,
        "token": token
    }

    response = {
        "statusCode": 200,
        "body": json.dumps(body)
    }
    return response
Ejemplo n.º 34
0
def parse_cookie(cookie):
    if cookie == '':
        return {}
    try:
        c = SimpleCookie()
        c.load(cookie)
    except CookieError:
        # Invalid cookie
        return {}

    cookiedict = {}
    for key in list(c.keys()):
        cookiedict[key] = c.get(key).value
    return cookiedict
Ejemplo n.º 35
0
    def _do_cookieguard(self, override=None):
        do_cg = override
        if do_cg is None: do_cg = getattr(self, 'pox_cookieguard', True)
        if not do_cg: return True

        requested = self.raw_requestline.split()[1].decode("latin-1")

        cookies = SimpleCookie(self.headers.get('Cookie'))
        cgc = cookies.get(self._pox_cookieguard_cookie_name)
        if cgc and cgc.value == self._get_cookieguard_cookie():
            if requested.startswith(self._pox_cookieguard_bouncer + "?"):
                log.debug("POX CookieGuard cookie is valid -- bouncing")
                qs = requested.split("?", 1)[1]

                self._cookieguard_maybe_consume_post()
                self.send_response(307, "Temporary Redirect")
                self.send_header("Location", unquote_plus(qs))
                self.end_headers()
                return False

            log.debug("POX CookieGuard cookie is valid")
            return True
        else:
            # No guard cookie or guard cookie is wrong
            if requested.startswith(self._pox_cookieguard_bouncer + "?"):
                # Client probably didn't save cookie
                qs = requested.split("?", 1)[1]
                target = unquote_plus(qs)
                bad_qs = quote_plus(target) != qs
                if bad_qs or self.command != "GET":
                    log.warn(
                        "Bad POX CookieGuard bounce; possible attack "
                        "(method:%s cookie:%s qs:%s)", self.command,
                        "bad" if cgc else "missing",
                        "bad" if bad_qs else "okay")
                    self.send_response(400, "Bad Request")
                    self.end_headers()
                    return False

                self._do_cookieguard_explict_continuation(requested, target)
                return False

            if cgc:
                log.debug(
                    "POX CookieGuard got wrong cookie -- setting new one")
            else:
                log.debug("POX CookieGuard got no cookie -- setting one")

            self._do_cookieguard_set_cookie(requested, bool(cgc))
            return False
Ejemplo n.º 36
0
def cookie_parts(name, kaka):
    """
    Give me the parts of the cookie payload

    :param name: A name of a cookie object
    :param kaka: The cookie
    :return: A list of parts or None if there is no cookie object with the
        given name
    """
    cookie_obj = SimpleCookie(as_unicode(kaka))
    morsel = cookie_obj.get(name)
    if morsel:
        return morsel.value.split("|")
    else:
        return None
Ejemplo n.º 37
0
    def load_session(self, cookies):
        from http.cookies import SimpleCookie
        from beaker.session import Session
        from pyload.webui.interface import session

        cookies = SimpleCookie(cookies)
        sid = cookies.get(session.options['key'])
        if not sid:
            return None

        s = Session({}, use_cookies=False, id=sid.value, **session.options)
        if s.is_new:
            return None

        return s
Ejemplo n.º 38
0
 def _websocket_auth(self, queue_events_data: Dict[str, Dict[str, str]],
                     cookies: SimpleCookie) -> Generator[str, str, None]:
     message = {
         "req_id": self._get_request_id(),
         "type": "auth",
         "request": {
             "csrf_token": cookies.get(settings.CSRF_COOKIE_NAME),
             "queue_id": queue_events_data['queue_id'],
             "status_inquiries": []
         }
     }
     auth_frame_str = ujson.dumps(message)
     self.ws.write_message(ujson.dumps([auth_frame_str]))
     response_ack = yield self.ws.read_message()
     response_message = yield self.ws.read_message()
     raise gen.Return([response_ack, response_message])
Ejemplo n.º 39
0
    def init_session(self):
        cookie = SimpleCookie(self.headers.get("Cookie"))
        sid = cookie.get("_ldapauthd_sess", None)

        if sid:
            self.session_id = sid.value
            self.session = sessions[self.session_id]
            if self.session:
                # session_id is valid
                log.debug("Got valid session with id %s", self.session_id)
                return True
            log.debug("Got invalid session with id %s", self.session_id)

        (self.session_id, self.session) = sessions.new_session()
        log.debug("Initialized new session with id %s", self.session_id)
        return False
Ejemplo n.º 40
0
 def _websocket_auth(self, queue_events_data: Dict[str, Dict[str, str]],
                     cookies: SimpleCookie) -> Generator[str, str, None]:
     message = {
         "req_id": self._get_request_id(),
         "type": "auth",
         "request": {
             "csrf_token": cookies.get(settings.CSRF_COOKIE_NAME),
             "queue_id": queue_events_data['queue_id'],
             "status_inquiries": []
         }
     }
     auth_frame_str = ujson.dumps(message)
     self.ws.write_message(ujson.dumps([auth_frame_str]))
     response_ack = yield self.ws.read_message()
     response_message = yield self.ws.read_message()
     raise gen.Return([response_ack, response_message])
Ejemplo n.º 41
0
 def _websocket_auth(self, ws: Any,
                     queue_events_data: Dict[str, Dict[str, str]],
                     cookies: SimpleCookie) -> Generator[str, str, None]:
     auth_queue_id = ':'.join((queue_events_data['response']['queue_id'], '0'))
     message = {
         "req_id": auth_queue_id,
         "type": "auth",
         "request": {
             "csrf_token": cookies.get('csrftoken').coded_value,
             "queue_id": queue_events_data['response']['queue_id'],
             "status_inquiries": []
         }
     }
     auth_frame_str = ujson.dumps(message)
     ws.write_message(ujson.dumps([auth_frame_str]))
     response_ack = yield ws.read_message()
     response_message = yield ws.read_message()
     raise gen.Return([response_ack, response_message])
Ejemplo n.º 42
0
def parse_cookie(cookie):
    """Parse an `HTTP cookie`_ string.

    Return a dictionary of cookie name/values.
    """
    if not cookie:
        return {}
    if not isinstance(cookie, BaseCookie):
        try:
            c = SimpleCookie()
            c.load(cookie)
        except CookieError:  # pragma    nocover
            # Invalid cookie
            return {}
    else:
        c = cookie
    cookiedict = {}
    for key in c.keys():
        cookiedict[key] = c.get(key).value
    return cookiedict
Ejemplo n.º 43
0
    def _load_from_cookie(self, environ):
        cookie = SimpleCookie(environ.get("HTTP_COOKIE"))
        if not cookie:
            return
        morsel = cookie.get(COOKIE_KEY)
        if not morsel:
            return

        val = self._converter.decode(morsel.value)
        if not val:
            return
        assert isinstance(val, dict)

        if val['__creation'] + self._max_age < time.time():
            # Session has expired
            val = {}

        self.clear()
        self.update(val)
        self._changed = False
Ejemplo n.º 44
0
    def query_server(self, filename):
        conn = self.module.ICAPConnection(**self.conn_kwargs)
        conn.request('REQMOD', filename, read_content=False, **self.req_kwargs)
        resp = conn.getresponse()
        conn.close()

        # look for the headers defined inside
        # the RFC Draft for ICAP Extensions
        threat = resp.get_icap_header('X-Violations-Found')
        # multiple threats? try to parse the header values
        if threat is not None:
            try:
                values = threat.split('\n')
                # only read the human readable descriptions
                threats = [s.strip() for idx, s
                           in enumerate(values[1:]) if idx % 4 == 1]
                threat = '%s threat(s) found: %s' % \
                         (threats[0].strip(), ', '.join(threats))
            except:
                threat = 'Multiple threats found: %s' % threat
        if threat is None:
            # only a description
            threat = resp.get_icap_header('X-Virus-ID')
            if threat is not None:
                threat = 'Threat found: %s' % threat
        if threat is None:
            threat = resp.get_icap_header('X-Infection-Found')
            if threat is not None:
                # only return the human readable threat name
                cookie = SimpleCookie(threat)
                kv = cookie.get('Threat')
                if kv is not None:
                    threat = kv.value
            if threat is not None:
                threat = 'Threat found: %s' % threat

        return threat
Ejemplo n.º 45
0
 def parse_cookies(self):
     cookie_data = self.environ.get('HTTP_COOKIE', '')
     cookies = SimpleCookie()
     if cookie_data:
         cookies.load(cookie_data)
     return {key: cookies.get(key).value for key in cookies.keys()}
Ejemplo n.º 46
0
class StreamResponse(HeadersMixin):

    def __init__(self, *, status=200, reason=None, headers=None):
        self._body = None
        self._keep_alive = None
        self._chunked = False
        self._chunk_size = None
        self._compression = False
        self._compression_force = False
        self._headers = CIMultiDict()
        self._cookies = SimpleCookie()

        self._req = None
        self._resp_impl = None
        self._eof_sent = False

        self._task = None

        if headers is not None:
            # TODO: optimize CIMultiDict extending
            self._headers.extend(headers)
        self._headers.setdefault(hdrs.CONTENT_TYPE, 'application/octet-stream')

        self.set_status(status, reason)

    @property
    def prepared(self):
        return self._resp_impl is not None

    @property
    def started(self):
        warnings.warn('use Response.prepared instead', DeprecationWarning)
        return self.prepared

    @property
    def task(self):
        return self._task

    @property
    def status(self):
        return self._status

    @property
    def chunked(self):
        return self._chunked

    @property
    def compression(self):
        return self._compression

    @property
    def reason(self):
        return self._reason

    def set_status(self, status, reason=None):
        if self.prepared:
            raise RuntimeError("Cannot change the response status code after "
                               "the headers have been sent")
        self._status = int(status)
        if reason is None:
            reason = ResponseImpl.calc_reason(status)
        self._reason = reason

    @property
    def keep_alive(self):
        return self._keep_alive

    def force_close(self):
        self._keep_alive = False

    @property
    def body_length(self):
        return self._resp_impl.body_length

    @property
    def output_length(self):
        return self._resp_impl.output_length

    def enable_chunked_encoding(self, chunk_size=None):
        """Enables automatic chunked transfer encoding."""
        self._chunked = True
        self._chunk_size = chunk_size

    def enable_compression(self, force=None):
        """Enables response compression encoding."""
        # Backwards compatibility for when force was a bool <0.17.
        if type(force) == bool:
            force = ContentCoding.deflate if force else ContentCoding.identity
        elif force is not None:
            assert isinstance(force, ContentCoding), ("force should one of "
                                                      "None, bool or "
                                                      "ContentEncoding")

        self._compression = True
        self._compression_force = force

    @property
    def headers(self):
        return self._headers

    @property
    def cookies(self):
        return self._cookies

    def set_cookie(self, name, value, *, expires=None,
                   domain=None, max_age=None, path='/',
                   secure=None, httponly=None, version=None):
        """Set or update response cookie.

        Sets new cookie or updates existent with new value.
        Also updates only those params which are not None.
        """

        old = self._cookies.get(name)
        if old is not None and old.coded_value == '':
            # deleted cookie
            self._cookies.pop(name, None)

        self._cookies[name] = value
        c = self._cookies[name]

        if expires is not None:
            c['expires'] = expires
        elif c.get('expires') == 'Thu, 01 Jan 1970 00:00:00 GMT':
            del c['expires']

        if domain is not None:
            c['domain'] = domain

        if max_age is not None:
            c['max-age'] = max_age
        elif 'max-age' in c:
            del c['max-age']

        c['path'] = path

        if secure is not None:
            c['secure'] = secure
        if httponly is not None:
            c['httponly'] = httponly
        if version is not None:
            c['version'] = version

    def del_cookie(self, name, *, domain=None, path='/'):
        """Delete cookie.

        Creates new empty expired cookie.
        """
        # TODO: do we need domain/path here?
        self._cookies.pop(name, None)
        self.set_cookie(name, '', max_age=0,
                        expires="Thu, 01 Jan 1970 00:00:00 GMT",
                        domain=domain, path=path)

    @property
    def content_length(self):
        # Just a placeholder for adding setter
        return super().content_length

    @content_length.setter
    def content_length(self, value):
        if value is not None:
            value = int(value)
            # TODO: raise error if chunked enabled
            self.headers[hdrs.CONTENT_LENGTH] = str(value)
        else:
            self.headers.pop(hdrs.CONTENT_LENGTH, None)

    @property
    def content_type(self):
        # Just a placeholder for adding setter
        return super().content_type

    @content_type.setter
    def content_type(self, value):
        self.content_type  # read header values if needed
        self._content_type = str(value)
        self._generate_content_type_header()

    @property
    def charset(self):
        # Just a placeholder for adding setter
        return super().charset

    @charset.setter
    def charset(self, value):
        ctype = self.content_type  # read header values if needed
        if ctype == 'application/octet-stream':
            raise RuntimeError("Setting charset for application/octet-stream "
                               "doesn't make sense, setup content_type first")
        if value is None:
            self._content_dict.pop('charset', None)
        else:
            self._content_dict['charset'] = str(value).lower()
        self._generate_content_type_header()

    @property
    def last_modified(self, _LAST_MODIFIED=hdrs.LAST_MODIFIED):
        """The value of Last-Modified HTTP header, or None.

        This header is represented as a `datetime` object.
        """
        httpdate = self.headers.get(_LAST_MODIFIED)
        if httpdate is not None:
            timetuple = parsedate(httpdate)
            if timetuple is not None:
                return datetime.datetime(*timetuple[:6],
                                         tzinfo=datetime.timezone.utc)
        return None

    @last_modified.setter
    def last_modified(self, value):
        if value is None:
            self.headers.pop(hdrs.LAST_MODIFIED, None)
        elif isinstance(value, (int, float)):
            self.headers[hdrs.LAST_MODIFIED] = time.strftime(
                "%a, %d %b %Y %H:%M:%S GMT", time.gmtime(math.ceil(value)))
        elif isinstance(value, datetime.datetime):
            self.headers[hdrs.LAST_MODIFIED] = time.strftime(
                "%a, %d %b %Y %H:%M:%S GMT", value.utctimetuple())
        elif isinstance(value, str):
            self.headers[hdrs.LAST_MODIFIED] = value

    @property
    def tcp_nodelay(self):
        resp_impl = self._resp_impl
        if resp_impl is None:
            raise RuntimeError("Cannot get tcp_nodelay for "
                               "not prepared response")
        return resp_impl.transport.tcp_nodelay

    def set_tcp_nodelay(self, value):
        resp_impl = self._resp_impl
        if resp_impl is None:
            raise RuntimeError("Cannot set tcp_nodelay for "
                               "not prepared response")
        resp_impl.transport.set_tcp_nodelay(value)

    @property
    def tcp_cork(self):
        resp_impl = self._resp_impl
        if resp_impl is None:
            raise RuntimeError("Cannot get tcp_cork for "
                               "not prepared response")
        return resp_impl.transport.tcp_cork

    def set_tcp_cork(self, value):
        resp_impl = self._resp_impl
        if resp_impl is None:
            raise RuntimeError("Cannot set tcp_cork for "
                               "not prepared response")
        resp_impl.transport.set_tcp_cork(value)

    def _generate_content_type_header(self, CONTENT_TYPE=hdrs.CONTENT_TYPE):
        params = '; '.join("%s=%s" % i for i in self._content_dict.items())
        if params:
            ctype = self._content_type + '; ' + params
        else:
            ctype = self._content_type
        self.headers[CONTENT_TYPE] = ctype

    def _start_pre_check(self, request):
        if self._resp_impl is not None:
            if self._req is not request:
                raise RuntimeError(
                    "Response has been started with different request.")
            else:
                return self._resp_impl
        else:
            return None

    def _do_start_compression(self, coding):
        if coding != ContentCoding.identity:
            self.headers[hdrs.CONTENT_ENCODING] = coding.value
            self._resp_impl.add_compression_filter(coding.value)
            self.content_length = None

    def _start_compression(self, request):
        if self._compression_force:
            self._do_start_compression(self._compression_force)
        else:
            accept_encoding = request.headers.get(
                hdrs.ACCEPT_ENCODING, '').lower()
            for coding in ContentCoding:
                if coding.value in accept_encoding:
                    self._do_start_compression(coding)
                    return

    def start(self, request):
        warnings.warn('use .prepare(request) instead', DeprecationWarning)
        resp_impl = self._start_pre_check(request)
        if resp_impl is not None:
            return resp_impl

        return self._start(request)

    @asyncio.coroutine
    def prepare(self, request):
        resp_impl = self._start_pre_check(request)
        if resp_impl is not None:
            return resp_impl
        yield from request._prepare_hook(self)

        return self._start(request)

    def _start(self, request,
               HttpVersion10=HttpVersion10,
               HttpVersion11=HttpVersion11,
               CONNECTION=hdrs.CONNECTION,
               DATE=hdrs.DATE,
               SERVER=hdrs.SERVER,
               SET_COOKIE=hdrs.SET_COOKIE,
               TRANSFER_ENCODING=hdrs.TRANSFER_ENCODING):
        self._req = request
        keep_alive = self._keep_alive
        if keep_alive is None:
            keep_alive = request.keep_alive
        self._keep_alive = keep_alive
        version = request.version

        resp_impl = self._resp_impl = ResponseImpl(
            request._writer,
            self._status,
            version,
            not keep_alive,
            self._reason)

        headers = self.headers
        for cookie in self._cookies.values():
            value = cookie.output(header='')[1:]
            headers.add(SET_COOKIE, value)

        if self._compression:
            self._start_compression(request)

        if self._chunked:
            if request.version != HttpVersion11:
                raise RuntimeError("Using chunked encoding is forbidden "
                                   "for HTTP/{0.major}.{0.minor}".format(
                                       request.version))
            resp_impl.chunked = True
            if self._chunk_size:
                resp_impl.add_chunking_filter(self._chunk_size)
            headers[TRANSFER_ENCODING] = 'chunked'
        else:
            resp_impl.length = self.content_length

        headers.setdefault(DATE, request.time_service.strtime())
        headers.setdefault(SERVER, resp_impl.SERVER_SOFTWARE)
        if CONNECTION not in headers:
            if keep_alive:
                if version == HttpVersion10:
                    headers[CONNECTION] = 'keep-alive'
            else:
                if version == HttpVersion11:
                    headers[CONNECTION] = 'close'

        resp_impl.headers = headers

        self._send_headers(resp_impl)
        self._task = request._task
        return resp_impl

    def _send_headers(self, resp_impl):
        # Durty hack required for
        # https://github.com/KeepSafe/aiohttp/issues/1093
        # File sender may override it
        resp_impl.send_headers()

    def write(self, data):
        assert isinstance(data, (bytes, bytearray, memoryview)), \
            "data argument must be byte-ish (%r)" % type(data)

        if self._eof_sent:
            raise RuntimeError("Cannot call write() after write_eof()")
        if self._resp_impl is None:
            raise RuntimeError("Cannot call write() before start()")

        if data:
            return self._resp_impl.write(data)
        else:
            return ()

    @asyncio.coroutine
    def drain(self):
        if self._resp_impl is None:
            raise RuntimeError("Response has not been started")
        yield from self._resp_impl.transport.drain()

    @asyncio.coroutine
    def write_eof(self):
        if self._eof_sent:
            return
        if self._resp_impl is None:
            raise RuntimeError("Response has not been started")

        yield from self._resp_impl.write_eof()
        self._eof_sent = True

    def __repr__(self):
        if self.started:
            info = "{} {} ".format(self._req.method, self._req.path)
        else:
            info = "not started"
        return "<{} {} {}>".format(self.__class__.__name__,
                                   self.reason, info)
Ejemplo n.º 47
0
class StreamResponse(collections.MutableMapping, HeadersMixin):

    _length_check = True

    def __init__(self, *, status=200, reason=None, headers=None):
        self._body = None
        self._keep_alive = None
        self._chunked = False
        self._compression = False
        self._compression_force = False
        self._cookies = SimpleCookie()

        self._req = None
        self._payload_writer = None
        self._eof_sent = False
        self._body_length = 0
        self._state = {}

        if headers is not None:
            self._headers = CIMultiDict(headers)
        else:
            self._headers = CIMultiDict()

        self.set_status(status, reason)

    @property
    def prepared(self):
        return self._payload_writer is not None

    @property
    def task(self):
        return getattr(self._req, 'task', None)

    @property
    def status(self):
        return self._status

    @property
    def chunked(self):
        return self._chunked

    @property
    def compression(self):
        return self._compression

    @property
    def reason(self):
        return self._reason

    def set_status(self, status, reason=None, _RESPONSES=RESPONSES):
        assert not self.prepared, \
            'Cannot change the response status code after ' \
            'the headers have been sent'
        self._status = int(status)
        if reason is None:
            try:
                reason = _RESPONSES[self._status][0]
            except Exception:
                reason = ''
        self._reason = reason

    @property
    def keep_alive(self):
        return self._keep_alive

    def force_close(self):
        self._keep_alive = False

    @property
    def body_length(self):
        return self._body_length

    @property
    def output_length(self):
        warnings.warn('output_length is deprecated', DeprecationWarning)
        return self._payload_writer.buffer_size

    def enable_chunked_encoding(self, chunk_size=None):
        """Enables automatic chunked transfer encoding."""
        self._chunked = True

        if hdrs.CONTENT_LENGTH in self._headers:
            raise RuntimeError("You can't enable chunked encoding when "
                               "a content length is set")
        if chunk_size is not None:
            warnings.warn('Chunk size is deprecated #1615', DeprecationWarning)

    def enable_compression(self, force=None):
        """Enables response compression encoding."""
        # Backwards compatibility for when force was a bool <0.17.
        if type(force) == bool:
            force = ContentCoding.deflate if force else ContentCoding.identity
        elif force is not None:
            assert isinstance(force, ContentCoding), ("force should one of "
                                                      "None, bool or "
                                                      "ContentEncoding")

        self._compression = True
        self._compression_force = force

    @property
    def headers(self):
        return self._headers

    @property
    def cookies(self):
        return self._cookies

    def set_cookie(self, name, value, *, expires=None,
                   domain=None, max_age=None, path='/',
                   secure=None, httponly=None, version=None):
        """Set or update response cookie.

        Sets new cookie or updates existent with new value.
        Also updates only those params which are not None.
        """

        old = self._cookies.get(name)
        if old is not None and old.coded_value == '':
            # deleted cookie
            self._cookies.pop(name, None)

        self._cookies[name] = value
        c = self._cookies[name]

        if expires is not None:
            c['expires'] = expires
        elif c.get('expires') == 'Thu, 01 Jan 1970 00:00:00 GMT':
            del c['expires']

        if domain is not None:
            c['domain'] = domain

        if max_age is not None:
            c['max-age'] = max_age
        elif 'max-age' in c:
            del c['max-age']

        c['path'] = path

        if secure is not None:
            c['secure'] = secure
        if httponly is not None:
            c['httponly'] = httponly
        if version is not None:
            c['version'] = version

    def del_cookie(self, name, *, domain=None, path='/'):
        """Delete cookie.

        Creates new empty expired cookie.
        """
        # TODO: do we need domain/path here?
        self._cookies.pop(name, None)
        self.set_cookie(name, '', max_age=0,
                        expires="Thu, 01 Jan 1970 00:00:00 GMT",
                        domain=domain, path=path)

    @property
    def content_length(self):
        # Just a placeholder for adding setter
        return super().content_length

    @content_length.setter
    def content_length(self, value):
        if value is not None:
            value = int(value)
            if self._chunked:
                raise RuntimeError("You can't set content length when "
                                   "chunked encoding is enable")
            self._headers[hdrs.CONTENT_LENGTH] = str(value)
        else:
            self._headers.pop(hdrs.CONTENT_LENGTH, None)

    @property
    def content_type(self):
        # Just a placeholder for adding setter
        return super().content_type

    @content_type.setter
    def content_type(self, value):
        self.content_type  # read header values if needed
        self._content_type = str(value)
        self._generate_content_type_header()

    @property
    def charset(self):
        # Just a placeholder for adding setter
        return super().charset

    @charset.setter
    def charset(self, value):
        ctype = self.content_type  # read header values if needed
        if ctype == 'application/octet-stream':
            raise RuntimeError("Setting charset for application/octet-stream "
                               "doesn't make sense, setup content_type first")
        if value is None:
            self._content_dict.pop('charset', None)
        else:
            self._content_dict['charset'] = str(value).lower()
        self._generate_content_type_header()

    @property
    def last_modified(self, _LAST_MODIFIED=hdrs.LAST_MODIFIED):
        """The value of Last-Modified HTTP header, or None.

        This header is represented as a `datetime` object.
        """
        httpdate = self.headers.get(_LAST_MODIFIED)
        if httpdate is not None:
            timetuple = parsedate(httpdate)
            if timetuple is not None:
                return datetime.datetime(*timetuple[:6],
                                         tzinfo=datetime.timezone.utc)
        return None

    @last_modified.setter
    def last_modified(self, value):
        if value is None:
            self.headers.pop(hdrs.LAST_MODIFIED, None)
        elif isinstance(value, (int, float)):
            self.headers[hdrs.LAST_MODIFIED] = time.strftime(
                "%a, %d %b %Y %H:%M:%S GMT", time.gmtime(math.ceil(value)))
        elif isinstance(value, datetime.datetime):
            self.headers[hdrs.LAST_MODIFIED] = time.strftime(
                "%a, %d %b %Y %H:%M:%S GMT", value.utctimetuple())
        elif isinstance(value, str):
            self.headers[hdrs.LAST_MODIFIED] = value

    def _generate_content_type_header(self, CONTENT_TYPE=hdrs.CONTENT_TYPE):
        params = '; '.join("%s=%s" % i for i in self._content_dict.items())
        if params:
            ctype = self._content_type + '; ' + params
        else:
            ctype = self._content_type
        self.headers[CONTENT_TYPE] = ctype

    def _do_start_compression(self, coding):
        if coding != ContentCoding.identity:
            self.headers[hdrs.CONTENT_ENCODING] = coding.value
            self._payload_writer.enable_compression(coding.value)
            # Compressed payload may have different content length,
            # remove the header
            self._headers.popall(hdrs.CONTENT_LENGTH, None)

    def _start_compression(self, request):
        if self._compression_force:
            self._do_start_compression(self._compression_force)
        else:
            accept_encoding = request.headers.get(
                hdrs.ACCEPT_ENCODING, '').lower()
            for coding in ContentCoding:
                if coding.value in accept_encoding:
                    self._do_start_compression(coding)
                    return

    async def prepare(self, request):
        if self._eof_sent:
            return
        if self._payload_writer is not None:
            return self._payload_writer

        await request._prepare_hook(self)
        return self._start(request)

    def _start(self, request,
               HttpVersion10=HttpVersion10,
               HttpVersion11=HttpVersion11,
               CONNECTION=hdrs.CONNECTION,
               DATE=hdrs.DATE,
               SERVER=hdrs.SERVER,
               CONTENT_TYPE=hdrs.CONTENT_TYPE,
               CONTENT_LENGTH=hdrs.CONTENT_LENGTH,
               SET_COOKIE=hdrs.SET_COOKIE,
               SERVER_SOFTWARE=SERVER_SOFTWARE,
               TRANSFER_ENCODING=hdrs.TRANSFER_ENCODING):
        self._req = request

        keep_alive = self._keep_alive
        if keep_alive is None:
            keep_alive = request.keep_alive
        self._keep_alive = keep_alive

        version = request.version
        writer = self._payload_writer = request._payload_writer

        headers = self._headers
        for cookie in self._cookies.values():
            value = cookie.output(header='')[1:]
            headers.add(SET_COOKIE, value)

        if self._compression:
            self._start_compression(request)

        if self._chunked:
            if version != HttpVersion11:
                raise RuntimeError(
                    "Using chunked encoding is forbidden "
                    "for HTTP/{0.major}.{0.minor}".format(request.version))
            writer.enable_chunking()
            headers[TRANSFER_ENCODING] = 'chunked'
            if CONTENT_LENGTH in headers:
                del headers[CONTENT_LENGTH]
        elif self._length_check:
            writer.length = self.content_length
            if writer.length is None:
                if version >= HttpVersion11:
                    writer.enable_chunking()
                    headers[TRANSFER_ENCODING] = 'chunked'
                    if CONTENT_LENGTH in headers:
                        del headers[CONTENT_LENGTH]
                else:
                    keep_alive = False

        headers.setdefault(CONTENT_TYPE, 'application/octet-stream')
        headers.setdefault(DATE, rfc822_formatted_time())
        headers.setdefault(SERVER, SERVER_SOFTWARE)

        # connection header
        if CONNECTION not in headers:
            if keep_alive:
                if version == HttpVersion10:
                    headers[CONNECTION] = 'keep-alive'
            else:
                if version == HttpVersion11:
                    headers[CONNECTION] = 'close'

        # status line
        status_line = 'HTTP/{}.{} {} {}\r\n'.format(
            version[0], version[1], self._status, self._reason)
        writer.write_headers(status_line, headers)

        return writer

    async def write(self, data):
        assert isinstance(data, (bytes, bytearray, memoryview)), \
            "data argument must be byte-ish (%r)" % type(data)

        if self._eof_sent:
            raise RuntimeError("Cannot call write() after write_eof()")
        if self._payload_writer is None:
            raise RuntimeError("Cannot call write() before prepare()")

        await self._payload_writer.write(data)

    async def drain(self):
        assert not self._eof_sent, "EOF has already been sent"
        assert self._payload_writer is not None, \
            "Response has not been started"
        warnings.warn("drain method is deprecated, use await resp.write()",
                      DeprecationWarning,
                      stacklevel=2)
        await self._payload_writer.drain()

    async def write_eof(self, data=b''):
        assert isinstance(data, (bytes, bytearray, memoryview)), \
            "data argument must be byte-ish (%r)" % type(data)

        if self._eof_sent:
            return

        assert self._payload_writer is not None, \
            "Response has not been started"

        await self._payload_writer.write_eof(data)
        self._eof_sent = True
        self._req = None
        self._body_length = self._payload_writer.output_size
        self._payload_writer = None

    def __repr__(self):
        if self._eof_sent:
            info = "eof"
        elif self.prepared:
            info = "{} {} ".format(self._req.method, self._req.path)
        else:
            info = "not prepared"
        return "<{} {} {}>".format(self.__class__.__name__,
                                   self.reason, info)

    def __getitem__(self, key):
        return self._state[key]

    def __setitem__(self, key, value):
        self._state[key] = value

    def __delitem__(self, key):
        del self._state[key]

    def __len__(self):
        return len(self._state)

    def __iter__(self):
        return iter(self._state)

    def __hash__(self):
        return hash(id(self))