def update_cookies(self, cookies): """Update request cookies header.""" if not cookies: return c = SimpleCookie() if hdrs.COOKIE in self.headers: c.load(self.headers.get(hdrs.COOKIE, '')) del self.headers[hdrs.COOKIE] for name, value in cookies.items(): if isinstance(value, Morsel): # Preserve coded_value mrsl_val = value.get(value.key, Morsel()) mrsl_val.set(value.key, value.value, value.coded_value) c[name] = mrsl_val else: c[name] = value self.headers[hdrs.COOKIE] = c.output(header='', sep=';').strip()
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 filter_cookies(self, request_url: URL = URL()) -> 'BaseCookie[str]': """Returns this jar's cookies filtered by their attributes.""" self._do_expiration() request_url = URL(request_url) filtered = SimpleCookie() hostname = request_url.raw_host or "" is_not_secure = request_url.scheme not in ("https", "wss") for cookie in self: name = cookie.key domain = cookie["domain"] path = cookie["path"] # Send shared cookies if not domain: filtered[name] = cookie.value continue if not self._unsafe and is_ip_address(hostname): continue if (domain, path, name) in self._host_only_cookies: if domain != hostname: continue elif not self._is_domain_match(domain, hostname): continue if not self._is_path_match(request_url.path, path): continue if is_not_secure and cookie["secure"]: continue # It's critical we use the Morsel so the coded_value # (based on cookie version) is preserved mrsl_val = cast('Morsel[str]', cookie.get(cookie.key, Morsel())) mrsl_val.set(cookie.key, cookie.value, cookie.coded_value) filtered[name] = mrsl_val return filtered
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 filter_cookies(self,request_url=URL()): #Returns this jar's cookies filtered by their attributes self._do_expiration() filtered = SimpleCookie() hostname = request_url.raw_host or '' is_not_secure = request_url.scheme not in ('https','wss') for cookie in self: name=cookie.key domain=cookie['domain'] # Send shared cookies if not domain: filtered[name]=cookie.value continue if not self.unsafe and is_ip_address(hostname): continue if (domain,name) in self.host_only_cookies: if domain!=hostname: continue elif not self._is_domain_match(domain,hostname): continue if not self._is_path_match(request_url.path,cookie['path']): continue if is_not_secure and cookie['secure']: continue # It's critical we use the Morsel so the coded_value # (based on cookie version) is preserved mrsl_val=cookie.get(cookie.key,Morsel()) mrsl_val.set(cookie.key,cookie.value, cookie.coded_value) filtered[name]=mrsl_val return filtered
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 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 test_morsel_to_cookie(self): from time import strftime, localtime time_template = "%a, %d-%b-%Y %H:%M:%S GMT" m = Morsel() m['domain'] = ".yandex" m['domain'] = ".yandex.ru" m['path'] = "/" m['expires'] = "Fri, 27-Aug-2021 17:43:25 GMT" m.key = "dj2enbdj3w" m.value = "fvjlrwnlkjnf" c = morsel_to_cookie(m) self.assertEqual(m.key, c.name) self.assertEqual(m.value, c.value) for x in ('expires', 'path', 'comment', 'domain', 'secure', 'version'): if x == 'expires': self.assertEqual( m[x], strftime(time_template, localtime(getattr(c, x, None)))) elif x == 'version': self.assertTrue(isinstance(getattr(c, x, None), int)) else: self.assertEqual(m[x], getattr(c, x, None))
def update_cookies(self, cookies: Optional[LooseCookies]) -> None: """Update request cookies header.""" if not cookies: return c = SimpleCookie() # type: SimpleCookie[str] if hdrs.COOKIE in self.headers: c.load(self.headers.get(hdrs.COOKIE, "")) del self.headers[hdrs.COOKIE] if isinstance(cookies, Mapping): iter_cookies = cookies.items() else: iter_cookies = cookies # type: ignore for name, value in iter_cookies: if isinstance(value, Morsel): # Preserve coded_value mrsl_val = value.get(value.key, Morsel()) mrsl_val.set(value.key, value.value, value.coded_value) c[name] = mrsl_val else: c[name] = value # type: ignore self.headers[hdrs.COOKIE] = c.output(header="", sep=";").strip()
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())
#!/usr/bin/env python3 import cgi import os import datetime from http.cookies import SimpleCookie, Morsel cookie_ = SimpleCookie(os.environ["HTTP_COOKIE"]) expiration = datetime.datetime.now() + datetime.timedelta(days=30) morsel = Morsel() morsel.key = "visits" morsel.value = "0" visits = int(cookie_.get("visits", morsel).value) + 1 cookie_["visits"] = str(visits) date_format = "%a, %d-%b-%Y %H:%M:%S %Z" cookie_["visits"]["expires"] = expiration.strftime(date_format) print("Content-type: text/html") print(cookie_.output(), "\n") print("<html><head><title>Cookies</title></head>") print("<body>") print("<h1>Cookie Example</h1>") print("<b>The Following header was sent:<br />", cookie_.output(), "</b><br/>") print("<div><h3># of visits: ", visits, "</h3></div><hr />") print("</body></html>")
def __set(self, arg1316, arg2304, arg633): "Private method for setting a cookie's value" var2405 = self.get(arg1316, Morsel()) var2405.set(arg1316, arg2304, arg633) dict.__setitem__(self, arg1316, var2405)
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 __set(self, key, real_value, coded_value): """Private method for setting a cookie's value""" M = self.get(key, Morsel()) M.set(key, real_value, coded_value) dict.__setitem__(self, key, M)
def setUp(self): self.cookie = Morsel() self.cookie.set('foo', 'bar', 'bar') self.cookie.time_received = time.time() - 1
def make_unset_morsel(name): m = Morsel() m.set(name, "", "") m["expires"] = format_expiration_date(1545335438.5059335) return m
def get_cookie(self, key): v = self.cookie.get(key, Morsel()).value return None if v is '_none' else v
<div>Click below to delete all cookies for this domain</div> <div><input type='submit' value="Delete All Cookies" /></div> </form> """ show_bgcolor_form = True cookie_ = SimpleCookie(os.environ["HTTP_COOKIE"]) fields = cgi.FieldStorage() if "bgcolor" in fields: bgcolor = fields['bgcolor'] cookie_["bgcolor"] = bgcolor show_bgcolor_form = False default = "" expiration = datetime.datetime.now() + datetime.timedelta(days=30) m1 = Morsel() m1.key="visits" m1.value="1" visits = int(cookie_.get("visits", m1).value) + 1 m2 = Morsel() m2.key="bgcolor" m2.value="#DDDDDD" bgcolor = cookie_.get("bgcolor", m2).value cookie_["visits"] = str(visits) cookie_["visits"]["expires"] = expiration.strftime("%a, %d-%b-%Y %H:%M:%S PST") cookie_["bgcolor"] = fields.getvalue('bgcolor', "inherit") styles = "body {{ background:{} }}".format(bgcolor) print("Content-type: text/html")