def cookies(self): jar = RequestsCookieJar() for name, cookie_dict in self['cookies'].items(): jar.set_cookie(create_cookie( name, cookie_dict.pop('value'), **cookie_dict)) jar.clear_expired_cookies() return jar
def cookies(self) -> RequestsCookieJar: jar = RequestsCookieJar() for name, cookie_dict in self['cookies'].items(): jar.set_cookie( create_cookie(name, cookie_dict.pop('value'), **cookie_dict)) jar.clear_expired_cookies() return jar
class Session(BaseConfigDict): helpurl = 'https://httpie.io/docs#sessions' about = 'HTTPie session file' def __init__( self, path: Union[str, Path], env: Environment, bound_host: str, session_id: str, suppress_legacy_warnings: bool = False, ): super().__init__(path=Path(path)) # Default values for the session files self['headers'] = [] self['cookies'] = [] self['auth'] = { 'type': None, 'username': None, 'password': None } # Runtime state of the Session objects. self.env = env self._headers = HTTPHeadersDict() self.cookie_jar = RequestsCookieJar() self.session_id = session_id self.bound_host = bound_host self.suppress_legacy_warnings = suppress_legacy_warnings def _add_cookies(self, cookies: List[Dict[str, Any]]) -> None: for cookie in cookies: domain = cookie.get('domain', '') if domain is None: # domain = None means explicitly lack of cookie, though # requests requires domain to be a string so we'll cast it # manually. cookie['domain'] = '' cookie['rest'] = {'is_explicit_none': True} self.cookie_jar.set(**cookie) def pre_process_data(self, data: Dict[str, Any]) -> Dict[str, Any]: for key, deserializer, importer in [ ('cookies', legacy_cookies.pre_process, self._add_cookies), ('headers', legacy_headers.pre_process, self._headers.update), ]: values = data.get(key) if values: normalized_values = deserializer(self, values) else: normalized_values = [] importer(normalized_values) return data def post_process_data(self, data: Dict[str, Any]) -> Dict[str, Any]: for key, store, serializer, exporter in [ ('cookies', self.cookie_jar, materialize_cookies, legacy_cookies.post_process), ('headers', self._headers, materialize_headers, legacy_headers.post_process), ]: original_type = type(data.get(key)) values = serializer(store) data[key] = exporter( values, original_type=original_type ) return data def _compute_new_headers(self, request_headers: HTTPHeadersDict) -> HTTPHeadersDict: new_headers = HTTPHeadersDict() for name, value in request_headers.copy().items(): if value is None: continue # Ignore explicitly unset headers original_value = value if type(value) is not str: value = value.decode() if name.lower() == 'user-agent' and value.startswith('HTTPie/'): continue if name.lower() == 'cookie': for cookie_name, morsel in SimpleCookie(value).items(): if not morsel['path']: morsel['path'] = DEFAULT_COOKIE_PATH self.cookie_jar.set(cookie_name, morsel) request_headers.remove_item(name, original_value) continue for prefix in SESSION_IGNORED_HEADER_PREFIXES: if name.lower().startswith(prefix.lower()): break else: new_headers.add(name, value) return new_headers def update_headers(self, request_headers: HTTPHeadersDict): """ Update the session headers with the request ones while ignoring certain name prefixes. """ new_headers = self._compute_new_headers(request_headers) new_keys = new_headers.copy().keys() # New headers will take priority over the existing ones, and override # them directly instead of extending them. for key, value in self._headers.copy().items(): if key in new_keys: continue new_headers.add(key, value) self._headers = new_headers @property def headers(self) -> HTTPHeadersDict: return self._headers.copy() @property def cookies(self) -> RequestsCookieJar: self.cookie_jar.clear_expired_cookies() return self.cookie_jar @cookies.setter def cookies(self, jar: RequestsCookieJar): self.cookie_jar = jar def remove_cookies(self, cookies: List[Dict[str, str]]): for cookie in cookies: remove_cookie_by_name( self.cookie_jar, cookie['name'], domain=cookie.get('domain', None), path=cookie.get('path', None) ) @property def auth(self) -> Optional[AuthBase]: auth = self.get('auth', None) if not auth or not auth['type']: return plugin = plugin_manager.get_auth_plugin(auth['type'])() credentials = {'username': None, 'password': None} try: # New style plugin.raw_auth = auth['raw_auth'] except KeyError: # Old style credentials = { 'username': auth['username'], 'password': auth['password'], } else: if plugin.auth_parse: from .cli.argtypes import parse_auth parsed = parse_auth(plugin.raw_auth) credentials = { 'username': parsed.key, 'password': parsed.value, } return plugin.get_auth(**credentials) @auth.setter def auth(self, auth: dict): assert {'type', 'raw_auth'} == auth.keys() self['auth'] = auth @property def is_anonymous(self): return is_anonymous_session(self.session_id) def warn_legacy_usage(self, warning: str) -> None: if self.suppress_legacy_warnings: return None self.env.log_error( warning, level=Levels.WARNING ) # We don't want to spam multiple warnings on each usage, # so if there is already a warning for the legacy usage # we'll skip the next ones. self.suppress_legacy_warnings = True
class Session(BaseConfigDict): helpurl = 'https://httpie.io/docs#sessions' about = 'HTTPie session file' def __init__( self, path: Union[str, Path], env: Environment, bound_host: str, session_id: str, refactor_mode: bool = False, ): super().__init__(path=Path(path)) self['headers'] = {} self['cookies'] = [] self['auth'] = { 'type': None, 'username': None, 'password': None } self.env = env self.cookie_jar = RequestsCookieJar() self.session_id = session_id self.bound_host = bound_host self.refactor_mode = refactor_mode def pre_process_data(self, data: Dict[str, Any]) -> Dict[str, Any]: cookies = data.get('cookies') if cookies: normalized_cookies = legacy_cookies.pre_process(self, cookies) else: normalized_cookies = [] for cookie in normalized_cookies: domain = cookie.get('domain', '') if domain is None: # domain = None means explicitly lack of cookie, though # requests requires domain to be a string so we'll cast it # manually. cookie['domain'] = '' cookie['rest'] = {'is_explicit_none': True} self.cookie_jar.set(**cookie) return data def post_process_data(self, data: Dict[str, Any]) -> Dict[str, Any]: cookies = data.get('cookies') normalized_cookies = [ materialize_cookie(cookie) for cookie in self.cookie_jar ] data['cookies'] = legacy_cookies.post_process( normalized_cookies, original_type=type(cookies) ) return data def update_headers(self, request_headers: HTTPHeadersDict): """ Update the session headers with the request ones while ignoring certain name prefixes. """ headers = self.headers for name, value in request_headers.copy().items(): if value is None: continue # Ignore explicitly unset headers original_value = value if type(value) is not str: value = value.decode() if name.lower() == 'user-agent' and value.startswith('HTTPie/'): continue if name.lower() == 'cookie': for cookie_name, morsel in SimpleCookie(value).items(): if not morsel['path']: morsel['path'] = DEFAULT_COOKIE_PATH self.cookie_jar.set(cookie_name, morsel) all_cookie_headers = request_headers.getall(name) if len(all_cookie_headers) > 1: all_cookie_headers.remove(original_value) else: request_headers.popall(name) continue for prefix in SESSION_IGNORED_HEADER_PREFIXES: if name.lower().startswith(prefix.lower()): break else: headers[name] = value self['headers'] = dict(headers) @property def headers(self) -> HTTPHeadersDict: return HTTPHeadersDict(self['headers']) @property def cookies(self) -> RequestsCookieJar: self.cookie_jar.clear_expired_cookies() return self.cookie_jar @cookies.setter def cookies(self, jar: RequestsCookieJar): self.cookie_jar = jar def remove_cookies(self, cookies: List[Dict[str, str]]): for cookie in cookies: remove_cookie_by_name( self.cookie_jar, cookie['name'], domain=cookie.get('domain', None), path=cookie.get('path', None) ) @property def auth(self) -> Optional[AuthBase]: auth = self.get('auth', None) if not auth or not auth['type']: return plugin = plugin_manager.get_auth_plugin(auth['type'])() credentials = {'username': None, 'password': None} try: # New style plugin.raw_auth = auth['raw_auth'] except KeyError: # Old style credentials = { 'username': auth['username'], 'password': auth['password'], } else: if plugin.auth_parse: from .cli.argtypes import parse_auth parsed = parse_auth(plugin.raw_auth) credentials = { 'username': parsed.key, 'password': parsed.value, } return plugin.get_auth(**credentials) @auth.setter def auth(self, auth: dict): assert {'type', 'raw_auth'} == auth.keys() self['auth'] = auth @property def is_anonymous(self): return is_anonymous_session(self.session_id)