def add_cookie(self, key, value, **attrs): """ Finer control over cookies. Allow specifying an Morsel arguments. """ if attrs: c = Morsel() c.set(key, value, **attrs) self.cookies[key] = c else: self.cookies[key] = value
def dicts_to_morsels(cookies): morsels = [] for cookie in cookies: name = cookie["name"] value = cookie["value"] m = Morsel() m.set(name, value, value) m["domain"] = cookie.get("domain", "") m["path"] = cookie.get("path", "") morsels.append(m) return morsels
def clear_cookie(self, response, name): cookie = Morsel() cookie.set(name, 'invalid', 'invalid') cookie['httponly'] = True cookie['secure'] = not settings.DEBUG cookie['path'] = '/' cookie['expires'] = 0 if self.cookie_domain: cookie['domain'] = self.cookie_domain response.cookies[name] = cookie
def set_csrf(self, request, response): token = self.get_csrf_token(request) if not token: return cookie = Morsel() cookie.set(self.csrf_token_cookie_name, token, token) cookie['secure'] = not settings.DEBUG cookie['path'] = '/' if self.cookie_domain: cookie['domain'] = self.cookie_domain response.cookies['csrf_token'] = cookie
def set_cookie( self, name: str, value: typing.Optional[str] = None, domain: str = "www.codingame.com", ): if value is not None: morsel = Morsel() morsel.set(name, value, cookie_quote(value)) morsel["domain"] = domain self.__session.cookie_jar.update_cookies({name: morsel}) else: self.__session.cookie_jar._cookies.get(domain, {}).pop(name, None)
def set_cookie(pname='', pvalue='', pexpires=3000, pdomain=None, psecure=False, phttponly=False, ppath='/'): """Sets a cookie.""" morsel = Morsel() name, value = str(pname), str(pvalue) morsel.set(name, value, value) morsel['expires'] = (dt.utcnow() + td(seconds=pexpires)).strftime('%a, %d %b %Y %H:%M:%S %Z') if ppath: morsel['path'] = ppath if pdomain: morsel['domain'] = pdomain if psecure: morsel['secure'] = psecure if phttponly: morsel['httponly'] = True return {name:morsel}
def test_loose_cookies_types(loop) -> None: req = ClientRequest('get', URL('http://python.org'), loop=loop) morsel = Morsel() morsel.set(key='string', val='Another string', coded_val='really') accepted_types = [ [('str', BaseCookie())], [('str', morsel)], [('str', 'str'), ], {'str': BaseCookie()}, {'str': morsel}, {'str': 'str'}, SimpleCookie(), ] for loose_cookies_type in accepted_types: req.update_cookies(cookies=loose_cookies_type)
def cookie_login(self, response, persistent, token): if not self.cookie_name: raise CookieException( 'login attempt without a configured cookie name') cookie = Morsel() cookie.set(self.cookie_name, token, token) cookie['httponly'] = True cookie['secure'] = not settings.DEBUG cookie['path'] = '/' if self.cookie_domain: cookie['domain'] = self.cookie_domain if persistent: cookie['expires'] = self.validity_seconds response.cookies[self.cookie_name] = cookie
def setcookie(name, value, expires="", domain=None, secure=False, httponly=False, path=None): """Sets a cookie.""" morsel = Morsel() name, value = safestr(name), safestr(value) morsel.set(name, value, quote(value)) if isinstance(expires, int) and expires < 0: expires = -1_000_000_000 morsel["expires"] = expires morsel["path"] = path or ctx.homepath + "/" if domain: morsel["domain"] = domain if secure: morsel["secure"] = secure value = morsel.OutputString() if httponly: value += "; httponly" header("Set-Cookie", value)
def setcookie(name, value, expires = '', domain = None, secure = False, httponly = False, path = None): """Sets a cookie.""" morsel = Morsel() name, value = safestr(name), safestr(value) morsel.set(name, value, quote(value)) if isinstance(expires, int) and expires < 0: expires = -1000000000 morsel['expires'] = expires morsel['path'] = path or ctx.homepath + '/' if domain: morsel['domain'] = domain if secure: morsel['secure'] = secure value = morsel.OutputString() if httponly: value += '; httponly' header('Set-Cookie', value)
def setcookie(name, value, expires='', domain=None, secure=False, httponly=False, path=None): """Sets a cookie.""" morsel = Morsel() name, value = safestr(name), safestr(value) morsel.set(name, value, quote(value)) if isinstance(expires, int) and expires < 0: expires = -1000000000 morsel['expires'] = expires morsel['path'] = path or ctx.homepath+'/' if domain: morsel['domain'] = domain if secure: morsel['secure'] = secure value = morsel.OutputString() if httponly: value += '; httponly' header('Set-Cookie', value)
async def import_aiohttp_cookies(cookiestxt_filename): cookies_obj = MozillaCookieJar(cookiestxt_filename) cookies_obj.load(ignore_discard=True, ignore_expires=True) cookies = CookieJar() cookies_list = [] for domain in cookies_obj._cookies.values(): for key, cookie in list(domain.values())[0].items(): c = Morsel() c.set(key, cookie.value, cookie.value) c['domain'] = cookie.domain c['path'] = cookie.path cookies_list.append((key, c)) cookies.update_cookies(cookies_list) return cookies
def make_cookie(name, value, expires='', path='', domain=None, secure=False, httponly=False): """Make a cookie string""" morsel = Morsel() morsel.set(name, value, quote(value)) if isinstance(expires, int) and expires < 0: expires = -1000000000 morsel['expires'] = expires morsel['path'] = path if domain: morsel['domain'] = domain if secure: morsel['secure'] = secure value = morsel.OutputString() if httponly: value += '; httponly' return value
def test_loose_cookies_types(loop: Any) -> None: req = ClientRequest("get", URL("http://python.org"), loop=loop) morsel = Morsel() morsel.set(key="string", val="Another string", coded_val="really") accepted_types = [ [("str", BaseCookie())], [("str", morsel)], [ ("str", "str"), ], {"str": BaseCookie()}, {"str": morsel}, {"str": "str"}, SimpleCookie(), ] for loose_cookies_type in accepted_types: req.update_cookies(cookies=loose_cookies_type)
def get_morsel(name, value, expires=-1, domain=None, secure=False, httponly=False, path=None): morsel = Morsel() morsel.set(name, value, quote(value)) if expires < 0: expires = -1000000000 morsel['expires'] = expires morsel['path'] = path if domain: morsel['domain'] = domain if secure: morsel['secure'] = secure value = morsel.OutputString() if httponly: value += '; httponly' return morsel
def run_attr_and_method(self): print('[{}]:'.format(inspect.getframeinfo(inspect.currentframe())[2])) m = Morsel() m.set('foo', 'bar', 'baz') print(f'key: {m.key}') # => key: foo print(f'value: {m.value}') # => value: bar print(f'coded_value: {m.coded_value}') # => coded_value: baz print(m) # => Set-Cookie: foo=baz print(m.output()) # => Set-Cookie: foo=baz print(m.OutputString()) # => foo=baz print(m.js_output())
def create_morsel(key, value, **kwargs): """Make a Morsel from underspecified parameters. """ morsel = Morsel() morsel.set(key, value, str(value)) result = { "version": "", "domain": "", "path": "/", "secure": "", "expires": "", "comment": "", "httponly": "", } badargs = set(kwargs) - set(result) if badargs: err = "create_cookie() got unexpected keyword arguments: %s" raise TypeError(err % list(badargs)) morsel.update(kwargs) return morsel
def force_clear_cookie(self, name, path="/", domain=None): """Deletes the cookie with the given name. Tornado's cookie handling currently (Jan 2018) stores cookies in a dict keyed by name, so it can only modify one cookie with a given name per response. The browser can store multiple cookies with the same name but different domains and/or paths. This method lets us clear multiple cookies with the same name. Due to limitations of the cookie protocol, you must pass the same path and domain to clear a cookie as were used when that cookie was set (but there is no way to find out on the server side which values were used for a given cookie). """ name = escape.native_str(name) expires = datetime.datetime.utcnow() - datetime.timedelta(days=365) morsel = Morsel() morsel.set(name, '', '""') morsel['expires'] = httputil.format_timestamp(expires) morsel['path'] = path if domain: morsel['domain'] = domain self.add_header("Set-Cookie", morsel.OutputString())
def set_cookie(self, name, value, path="/", domain=None, max_age=None, expires=None, secure=False, httponly=False, comment=None): """Set a cookie to be sent with a Set-Cookie header in the response :param name: name of the cookie (a binary string) :param value: value of the cookie (a binary string, or None) :param max_age: datetime.timedelta int representing the time (in seconds) until the cookie expires :param path: String path to which the cookie applies :param domain: String domain to which the cookie applies :param secure: Boolean indicating whether the cookie is marked as secure :param httponly: Boolean indicating whether the cookie is marked as HTTP Only :param comment: String comment :param expires: datetime.datetime or datetime.timedelta indicating a time or interval from now when the cookie expires """ # TODO(Python 3): Convert other parameters (e.g. path) to bytes, too. if value is None: value = b'' max_age = 0 expires = timedelta(days=-1) name = isomorphic_decode(name) value = isomorphic_decode(value) days = {i+1: name for i, name in enumerate(["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"])} if isinstance(expires, timedelta): expires = datetime.utcnow() + expires if expires is not None: expires_str = expires.strftime("%d %%s %Y %H:%M:%S GMT") expires_str = expires_str % days[expires.month] expires = expires_str if max_age is not None: if hasattr(max_age, "total_seconds"): max_age = int(max_age.total_seconds()) max_age = "%.0d" % max_age m = Morsel() def maybe_set(key, value): if value is not None and value is not False: m[key] = value m.set(name, value, value) maybe_set("path", path) maybe_set("domain", domain) maybe_set("comment", comment) maybe_set("expires", expires) maybe_set("max-age", max_age) maybe_set("secure", secure) maybe_set("httponly", httponly) self.headers.append("Set-Cookie", m.OutputString())
def __new__(cls, loop, method, url, headers, data, params, cookies, auth, proxy_url, proxy_auth, ssl): """ Creates a new ``ClientRequest`` instance with the given parameters. Parameters ---------- loop : ``EventThread`` The event loop, trough what the request is executed. method : `str` The request's method. url : ``URL`` The url to request. headers : `None`, `dict` or ``imultidict`` Headers of the request. data : `None`, `bytes-like`, `io-like`, ``Formdata` Data to send as the request's body. params : `dict` of (`str`, (`str`, `int`, `float`, `bool`)) items Query string parameters. cookies : `None` or ``CookieJar`` Cookies OwO. auth : `None` or ``BasicAuth`` Authorization sent with the request. proxy_url : `None` or ``URL`` Proxy url to use if applicable. proxy_auth : `None` or ``BasicAuth`` Proxy authorization sent with the request. ssl : `None` `None`, ``SSLContext``, `bool`, ``Fingerprint`` The connection's ssl type. Raises ------ TypeError - `proxy_auth`'s type is incorrect. - ˙Cannot serialize a field of the given `data`. ValueError - Host could not be detected from `url`. - The `proxy_url`'s scheme is not `http`. - `compression` and `Content-Encoding` would be set at the same time. - `chunked` cannot be set, because `Transfer-Encoding: chunked` is already set. - `chunked` cannot be set, because `Content-Length` header is already present. RuntimeError - If one of `data`'s field's content has unknown content-encoding. - If one of `data`'s field's content has unknown content-transfer-encoding. """ # Convert headers headers = imultidict(headers) # Add extra query parameters to the url and remove fragments url = url.extend_query(params) request_url = url.with_fragment(None) if not url.host: raise ValueError('Host could not be detected.') # Check authorization if auth is None: # If authorization is given, try to detect from url. username = url.user password = url.password if (username is not None) and username: if password is None: password = '' auth = BasicAuth(username, password) # Store auth in headers is applicable. if (auth is not None): headers[AUTHORIZATION] = auth.encode() for key, value in DEFAULT_HEADERS: headers.setdefault(key, value) # Add host to headers if not present. if HOST not in headers: netloc = request_url.raw_host if not request_url.is_default_port(): netloc = f'{netloc}:{request_url.port}' headers[HOST] = netloc # Update cookies if (cookies is not None) and cookies: cookie = SimpleCookie() if COOKIE in headers: cookie.load(headers.get(COOKIE, '')) del headers[COOKIE] for key, value in cookies.items(): if isinstance(key, Morsel): # Preserve coded_value try: morsel_value = value.get(value.key, None) except KeyError: morsel_value = Morsel() morsel_value.set(value.key, value.value, value.coded_value) value = morsel_value cookie[key] = value headers[COOKIE] = cookie.output(header='', sep=';').strip() # Check proxy settings. if proxy_url is not None: if proxy_url.scheme != 'http': raise ValueError( f'Only http proxies are supported, got {proxy_url!r}.') if (proxy_auth is not None): proxy_auth_type = proxy_auth.__class__ if proxy_auth_type is not BasicAuth: raise TypeError( f'`proxy_auth` must be `None` or `{BasicAuth.__name__}`, got ' f'{proxy_auth_type.__name__}.') # Needed for transfer data checks chunked = True compression = headers.get(CONTENT_ENCODING, None) # Get request content encoding. if (data is not None): if data: if (compression is not None): if headers.get(CONTENT_ENCODING, ''): raise ValueError( 'Compression can not be set if `Content-Encoding` header is set.' ) chunked = True # formdata if isinstance(data, Formdata): data = data() else: try: data = create_payload(data, {'disposition': None}) except LookupError: data = Formdata.from_fields(data)() if not chunked: if CONTENT_LENGTH not in headers: size = data.size if size is None: chunked = True else: if CONTENT_LENGTH not in headers: headers[CONTENT_LENGTH] = str(size) if CONTENT_TYPE not in headers: headers[CONTENT_TYPE] = data.content_type data_headers = data.headers if data_headers: for key, value in data_headers.items(): headers.setdefault(key, value) else: data = None # Analyze transfer-encoding header. transfer_encoding = headers.get(TRANSFER_ENCODING, '').lower() if 'chunked' in transfer_encoding: if chunked: raise ValueError( 'Chunked can not be set if `Transfer-Encoding: chunked` header is already set.' ) elif chunked: if CONTENT_LENGTH in headers: raise ValueError( 'Chunked can not be set if `Content-Length` header is set.' ) headers[TRANSFER_ENCODING] = 'chunked' else: if CONTENT_LENGTH not in headers: headers[CONTENT_LENGTH] = '0' if data is None else str( len(data)) # Set default content-type. if (method in METHOD_POST_ALL) and (CONTENT_TYPE not in headers): headers[CONTENT_TYPE] = 'application/octet-stream' # Everything seems correct, create the object. self = object.__new__(cls) self.original_url = url self.url = request_url self.method = method self.loop = loop self.ssl = ssl self.chunked = chunked self.compression = compression self.body = data self.auth = auth self.writer = None self.response = None self.headers = headers self.proxy_url = proxy_url self.proxy_auth = proxy_auth return self
def make_unset_morsel(name): m = Morsel() m.set(name, "", "") m["expires"] = format_expiration_date(1545335438.5059335) return m