def unset_cookie(self, key): """ Unset a cookie with the given name (remove it from the response). If there are multiple cookies (e.g., two cookies with the same name and different paths or domains), all such cookies will be deleted. """ existing = self.response.headers.get_all('Set-Cookie') if not existing: raise KeyError( "No cookies at all have been set") del self.response.headers['Set-Cookie'] found = False for header in existing: cookies = BaseCookie() cookies.load(header) if key in cookies: found = True del cookies[key] header = cookies.output(header='').lstrip() if header: self.response.headers.add('Set-Cookie', header) if not found: raise KeyError( "No cookie has been set with the name %r" % key)
def unset_cookie(self, key, strict=True): """ Unset a cookie with the given name (remove it from the response). If there are multiple cookies (e.g., two cookies with the same name and different paths or domains), all such cookies will be deleted. """ existing = self.headers.getall('Set-Cookie') if not existing: if not strict: return raise KeyError("No cookies at all have been set") del self.headers['Set-Cookie'] found = False for header in existing: cookies = BaseCookie() cookies.load(header) if key in cookies: found = True del cookies[key] self._add_cookie(cookies) else: # this branching is required because Cookie.Morsel.output() # strips quotes from expires= parameter, so better use # it as is, if it hasn't changed self._add_cookie(header) if strict and not found: raise KeyError( "No cookie has been set with the name %r" % key)
def do_request(self, req): errors = StringIO() req.environ['wsgi.errors'] = errors if self.cookies: cookie_header = ''.join([ '%s="%s"; ' % (name, cookie_quote(value)) for name, value in self.cookies.items()]) req.environ['HTTP_COOKIE'] = cookie_header res = req.get_response(self.application, catch_exc_info=True) # We do this to make sure the app_iter is exausted: res.body res.errors = errors.getvalue() res.cookies_set = {} for header in res.headers.getall('set-cookie'): try: c = BaseCookie(header) except CookieError, e: raise CookieError( "Could not parse cookie header %r: %s" % (header, e)) for key, morsel in c.items(): self.cookies[key] = morsel.value res.cookies_set[key] = morsel.value
def do_request(self, req, status, expect_errors): """ Override webtest.TestApp's method so that we do real HTTP requests instead of WSGI calls. """ headers = {} if self.cookies: c = BaseCookie() for name, value in self.cookies.items(): c[name] = value hc = '; '.join(['='.join([m.key, m.value]) for m in c.values()]) req.headers['Cookie'] = hc res = self._do_httplib_request(req) # Set these attributes for consistency with webtest. res.request = req res.test_app = self if not expect_errors: self._check_status(res.status_int, res) self._check_errors(res) res.cookies_set = {} # merge cookies back in self.cookiejar.extract_cookies(ResponseCookieAdapter(res), RequestCookieAdapter(req)) return res
def load(self, rawdata): self.bad_cookies = [] self._BaseCookie__set = self._loose_set BaseCookie.load(self, rawdata) self._BaseCookie__set = self._strict_set for key in self.bad_cookies: del self[key]
def unset_cookie(self, key): """ Unset a cookie with the given name (remove from the response). If there are multiple cookies (e.g., two cookies with the same name and different paths or domains), all such cookies will be deleted. Args: key: string that is the cookie's name (mandatory) Side effects: delete from self.response.headers all cookies with that name Raises: KeyError if the response had no such cookies (or, none at all) """ existing = self.response.headers.getall('Set-Cookie') if not existing: raise KeyError("No cookies at all had been set") # remove all set-cookie headers, then put back those (if any) that # should not be removed del self.response.headers['Set-Cookie'] found = False for header in existing: cookies = BaseCookie() cookies.load(header) if key in cookies: found = True del cookies[key] header = cookies.output(header='').lstrip() if header: self.response.headers.add_header('Set-Cookie', header) if not found: raise KeyError("No cookie had been set with name %r" % key)
def do_request(self, req, status, expect_errors): """ Override webtest.TestApp's method so that we do real HTTP requests instead of WSGI calls. """ headers = {} if self.cookies: c = BaseCookie() for name, value in self.cookies.items(): c[name] = value hc = '; '.join(['='.join([m.key, m.value]) for m in c.values()]) req.headers['Cookie'] = hc res = self._do_httplib_request(req) # Set these attributes for consistency with webtest. res.request = req res.test_app = self if not expect_errors: self._check_status(res.status_int, res) self._check_errors(res) res.cookies_set = {} for header in res.headers.getall('set-cookie'): try: c = BaseCookie(header) except CookieError, e: raise CookieError( "Could not parse cookie header %r: %s" % (header, e)) for key, morsel in c.items(): self.cookies[key] = morsel.value res.cookies_set[key] = morsel.value
def unset_cookie(self, key, strict=True): """ Unset a cookie with the given name (remove it from the response). If there are multiple cookies (e.g., two cookies with the same name and different paths or domains), all such cookies will be deleted. """ existing = self.headers.getall('Set-Cookie') if not existing: if not strict: return raise KeyError("No cookies at all have been set") del self.headers['Set-Cookie'] found = False for header in existing: cookies = BaseCookie() cookies.load(header) if key in cookies: found = True del cookies[key] self._add_cookie(cookies) else: # this branching is required because Cookie.Morsel.output() # strips quotes from expires= parameter, so better use # it as is, if it hasn't changed self._add_cookie(header) if strict and not found: raise KeyError("No cookie has been set with the name %r" % key)
def prepareResponse(self, response): for key, value in response.headers.items(): if key.lower() == "set-cookie": cookie = BaseCookie(value) # use all attributes but 'secure', because then the browser won't send the cookie anymore value = cookie.output(attrs=['expires','path','comment','domain','max-age','secure','version','httponly'], header="") self.setHeader(key, value) self.setResponseCode(response.code)
def parse_cookies(response): """ Return a ``Cookie.BaseCookie`` object populated from cookies parsed from the response object """ base_cookie = BaseCookie() for item in response.headers.get_all('Set-Cookie'): base_cookie.load(item) return base_cookie
def do_request(self, req, status, expect_errors): """ Executes the given request (``req``), with the expected ``status``. Generally ``.get()`` and ``.post()`` are used instead. """ __tracebackhide__ = True errors = StringIO() req.environ["wsgi.errors"] = errors if self.cookies: c = BaseCookie() for name, value in self.cookies.items(): c[name] = value req.environ["HTTP_COOKIE"] = str(c).split(": ", 1)[1] req.environ["paste.testing"] = True req.environ["paste.testing_variables"] = {} app = lint.middleware(self.app) old_stdout = sys.stdout out = CaptureStdout(old_stdout) try: sys.stdout = out start_time = time.time() ## FIXME: should it be an option to not catch exc_info? res = req.get_response(app, catch_exc_info=True) end_time = time.time() finally: sys.stdout = old_stdout sys.stderr.write(out.getvalue()) res.app = app res.test_app = self # We do this to make sure the app_iter is exausted: res.body res.errors = errors.getvalue() total_time = end_time - start_time for name, value in req.environ["paste.testing_variables"].items(): if hasattr(res, name): raise ValueError( "paste.testing_variables contains the variable %r, but " "the response object already has an attribute by that " "name" % name ) setattr(res, name, value) if not expect_errors: self._check_status(status, res) self._check_errors(res) res.cookies_set = {} for header in res.headers.getall("set-cookie"): try: c = BaseCookie(header) except CookieError, e: raise CookieError("Could not parse cookie header %r: %s" % (header, e)) for key, morsel in c.items(): self.cookies[key] = morsel.value res.cookies_set[key] = morsel.value
def do_request(self, req, status, expect_errors): """ Executes the given request (``req``), with the expected ``status``. Generally ``.get()`` and ``.post()`` are used instead. """ __tracebackhide__ = True errors = StringIO() req.environ['wsgi.errors'] = errors if self.cookies: c = BaseCookie() for name, value in self.cookies.items(): c[name] = value req.environ['HTTP_COOKIE'] = str(c).split(': ', 1)[1] req.environ['paste.testing'] = True req.environ['paste.testing_variables'] = {} app = lint.middleware(self.app) old_stdout = sys.stdout out = CaptureStdout(old_stdout) try: sys.stdout = out start_time = time.time() ## FIXME: should it be an option to not catch exc_info? res = req.get_response(app, catch_exc_info=True) end_time = time.time() finally: sys.stdout = old_stdout sys.stderr.write(out.getvalue()) res.app = app res.test_app = self # We do this to make sure the app_iter is exausted: res.body res.errors = errors.getvalue() total_time = end_time - start_time for name, value in req.environ['paste.testing_variables'].items(): if hasattr(res, name): raise ValueError( "paste.testing_variables contains the variable %r, but " "the response object already has an attribute by that " "name" % name) setattr(res, name, value) if not expect_errors: self._check_status(status, res) self._check_errors(res) res.cookies_set = {} for header in res.headers.getall('set-cookie'): try: c = BaseCookie(header) except CookieError, e: raise CookieError("Could not parse cookie header %r: %s" % (header, e)) for key, morsel in c.items(): self.cookies[key] = morsel.value res.cookies_set[key] = morsel.value
def prepareResponse(self, response): for key, value in response.headers.items(): if key.lower() == "set-cookie": cookie = BaseCookie(value) # use all attributes but 'secure', because then the browser won't send the cookie anymore value = cookie.output(attrs=[ 'expires', 'path', 'comment', 'domain', 'max-age', 'secure', 'version', 'httponly' ], header="") self.setHeader(key, value) self.setResponseCode(response.code)
def _parse_cookies(self, environ): source = environ.get('HTTP_COOKIE', '') vars = {} if source: cookies = BaseCookie() cookies.load(source) for name in cookies: value = cookies[name].value unquote_match = _QUOTES_RE.match(value) if unquote_match is not None: value = unquote_match.group(1) vars[name] = value return vars
def _parse_cookies(self, environ) : _QUOTES_RE = re.compile('"(.*)"') source=environ.get('HTTP_COOKIE', '') vars = {} if source: cookies = BaseCookie() cookies.load(source) for name in cookies: value = cookies[name].value unquote_match = _QUOTES_RE.match(value) if unquote_match is not None: value = unquote_match.group(1) vars[name] = value return vars
def enc_setcookie(val, typ='req'): vals = val.split('\x00') encoded = '' for v in vals: if len(encoded) > 0: encoded += '\x00' v = v.replace(']', '_') # work around parsing bug for some cookie values v = v.replace('[', '_') cookie = BaseCookie(v) for n in cookie: morsel = cookie[n] encoded += '.' #TODO non-op... represent the bit flags.. add these in later encoded += enc_uvarint(len(n)) encoded += n value = attempt_decode(morsel.value) encoded += enc_uvarint(len(value)) encoded += value for f in ['path', 'domain']: l = len(morsel[f]) encoded += struct.pack('!H', l) if l > 0: encoded += morsel[f] if len(morsel['max-age']) > 0: encoded += enc_uvarint(morsel['max-age']) else: encoded += enc_date(morsel['expires']) return encoded
def update_cookie(response, session_key): cookie = BaseCookie() cookie['skey'] = session_key cookie['skey']['path'] = '/' cookie['skey']['max-age'] = 17299119 response.headers.add('Set-Cookie', cookie['skey'].output(header='').strip())
def set_cookie(self, key, value='', max_age=None, path='/', domain=None, secure=None, httponly=False, version=None, comment=None): """ Set (add) a cookie for the response """ cookies = BaseCookie() cookies[key] = value for var_name, var_value in [ ('max-age', max_age), ('path', path), ('domain', domain), ('secure', secure), ('HttpOnly', httponly), ('version', version), ('comment', comment), ]: if var_value is not None and var_value is not False: cookies[key][var_name] = str(var_value) if max_age is not None: cookies[key]['expires'] = max_age header_value = cookies[key].output(header='').lstrip() self.response.headers._headers.append(('Set-Cookie', header_value))
def _get_cookies(environ): """ Return a *plain* dictionary of cookies as found in the request. """ source = environ.get('HTTP_COOKIE', '') if 'webob._parsed_cookies' in environ: vars_, var_source = environ['webob._parsed_cookies'] if var_source == source: return vars_ vars_ = {} if source: cookies = BaseCookie() cookies.load(source) for name in cookies: vars_[name] = cookies[name].value environ['webob._parsed_cookies'] = (vars_, source) return vars_
def transferCookiesToSafari(): """ Copy all crunchyroll cookies from Plex's cookie storage into Safari's Plist """ import platform if "darwin" in platform.system().lower(): cookieString = HTTP.GetCookiesForURL(BASE_URL) if not cookieString: return True try: theCookies = BaseCookie(cookieString) appendThis = [] tomorrow = datetime.now() + timedelta((1)) for k, v in theCookies.items(): #Plex doesn't supply these, so: cookieDict = { 'Domain': ".crunchyroll.com", 'Path': "/", 'Expires': tomorrow, 'Created': time.time(), 'Name': k, 'Value': v.value } appendThis.append(cookieDict) #Log.Debug("#######Transferring these cookies:") #Log.Debug(appendThis) filename = os.path.expanduser("~/Library/Cookies/Cookies.plist") theList = plistlib.readPlist(filename) finalCookies = appendThis # brute force replace for item in theList: if not "crunchyroll.com" in item['Domain']: finalCookies.append(item) plistlib.writePlist(finalCookies, filename) return True except Exception, arg: Log.Error("#########transferCookiesToSafari() Exception occured:") Log.Error(repr(Exception) + " " + repr(arg)) return False
def set_cookie(response, key, value='', max_age_days=0, path='/'): from Cookie import BaseCookie cookies = BaseCookie() cookies[key] = value morsel = cookies[key] morsel['max-age'] = max_age_days * 86400 morsel['path'] = path output = morsel.output(header='') response.headers.add_header('Set-Cookie', output)
def get_user(request, secret_filename): """ Can raise IOError (in secret=, if secret_filename is not configured right) Can raise KeyError (in morsel=, if no cookie) Can raise BadCookie or NotAuthenticated """ secret = get_secret(secret_filename) morsel = BaseCookie(request.environ['HTTP_COOKIE'])['__ac'] username, hash = authenticate_from_cookie(morsel.value, secret) return username
def set_cookie(self, name, value, domain=None, expires=None, path='/', expires_days=None): """Sets the given cookie name/value with the given options. :param name: Cookie name. :param value: Cookie value. :param domain: Cookie domain. :param expires: A expiration date as a `datetime` object. :param path: Cookie path. :param expires_days: Number of days to calculate expiration. :return: `None`. """ if expires_days is not None and not expires: expires = datetime.datetime.utcnow() + datetime.timedelta( days=expires_days) cookie = BaseCookie() cookie[name] = str(base64.b64encode(value)) if expires: timestamp = calendar.timegm(expires.utctimetuple()) expires = email.utils.formatdate(timestamp, localtime=False, usegmt=True) cookie[name]['expires'] = expires if path: cookie[name]['path'] = path if domain: cookie[name]['domain'] = domain cookie_str = cookie.output() if cookie_str.startswith('Set-Cookie:'): cookie_str = cookie_str[11:].strip() self._response.headers.add_header('Set-Cookie', cookie_str)
def transferCookiesToSafari(): """ Copy all crunchyroll cookies from Plex's cookie storage into Safari's Plist """ import platform if "darwin" in platform.system().lower(): cookieString = HTTP.GetCookiesForURL(BASE_URL) if not cookieString: return True try: theCookies = BaseCookie(cookieString) appendThis = [] tomorrow = datetime.now() + timedelta((1)) for k, v in theCookies.items(): #Plex doesn't supply these, so: cookieDict = {'Domain':".crunchyroll.com", 'Path':"/", 'Expires': tomorrow, 'Created': time.time(), 'Name': k, 'Value': v.value } appendThis.append(cookieDict) #Log.Debug("#######Transferring these cookies:") #Log.Debug(appendThis) filename = os.path.expanduser("~/Library/Cookies/Cookies.plist") theList = plistlib.readPlist(filename) finalCookies = appendThis # brute force replace for item in theList: if not "crunchyroll.com" in item['Domain']: finalCookies.append(item) plistlib.writePlist(finalCookies, filename) return True except Exception, arg: Log.Error("#########transferCookiesToSafari() Exception occured:") Log.Error(repr(Exception) + " " + repr(arg)) return False
def get_cookie(self, name): cookies = self.headers.get('Cookie') if cookies: authcookie = BaseCookie(cookies).get(name) if authcookie: return authcookie.value else: return None else: return None
def do_login(u, login, pwd): conn = httplib.HTTPConnection(u.hostname, u.port) conn.request('GET', u.path) r = conn.getresponse() if r.status != 200: raise Exception, r.status, r.reason h = pymayhem.FormRipper() h.feed(r.read()) f = findlogin(h.forms) if f is None: raise ValueError, 'login form not found' f['sausr'] = login f['sapwd'] = pwd params = f.get_form_data() headers = {'Content-type': 'application/x-www-form-urlencoded', 'Referer': u.geturl(), 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:14.0) Gecko/20100101 Firefox/14.0.1', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en-us,en;q=0.5' } lu = urlparse(f.action) conn = httplib.HTTPConnection(lu.hostname, lu.port) conn.request('POST', lu.path, params, headers) r = conn.getresponse() if r.status != 302: raise ValueError, 'bad response', r cookie = None location = None for (k, v) in r.getheaders(): if k == 'set-cookie': cookie = v elif k == 'location': location = urlparse(v) c = Cookie(cookie) c = c.output(c.keys(), '', ', ').strip() q = location.query return (c, q)
def get_user(request): try: morsel = BaseCookie(request.META['HTTP_COOKIE'])['__ac'] secret = settings.OPENCORE_SECRET_FILENAME secret = auth.get_secret(secret) username, hash = auth.authenticate_from_cookie( morsel.value, secret) except (IOError, KeyError, auth.BadCookie, auth.NotAuthenticated): return AnonymousUser() user, _ = User.objects.get_or_create(username=username) return user
def do_request(self, req, status, expect_errors): """ Override webtest.TestApp's method so that we do real HTTP requests instead of WSGI calls. """ headers = {} if self.cookies: c = BaseCookie() for name, value in self.cookies.items(): c[name] = value hc = '; '.join(['='.join([m.key, m.value]) for m in c.values()]) req.headers['Cookie'] = hc res = self._do_httplib_request(req) # Set these attributes for consistency with webtest. res.request = req res.test_app = self if not expect_errors: self._check_status(res.status_int, res) self._check_errors(res) res.cookies_set = {} for header in res.headers.getall('set-cookie'): try: c = BaseCookie(header) except CookieError, e: raise CookieError("Could not parse cookie header %r: %s" % (header, e)) for key, morsel in c.items(): self.cookies[key] = morsel.value res.cookies_set[key] = morsel.value
def str_cookies(self): """ Return a *plain* dictionary of cookies as found in the request. """ env = self.environ source = env.get('HTTP_COOKIE', '') if 'webob._parsed_cookies' in env: vars, var_source = env['webob._parsed_cookies'] if var_source == source: return vars vars = {} if source: cookies = BaseCookie() cookies.load(source) for name in cookies: value = cookies[name].value unquote_match = QUOTES_RE.match(value) if unquote_match is not None: value = unquote_match.group(1) vars[name] = value env['webob._parsed_cookies'] = (vars, source) return vars
def get_go_auth(ca_certs, username=None, password=None): """ POST the login form to www.globusonline.org to get the cookie, prompting for username and password on stdin if they were not passed as parameters. @return: a GOAuthResult instance. The cookie is what most clients will be interested in, but if the username is not passed as a parameter the caller may need that as well, and may want to cache the password. """ if ca_certs is None: from globusonline.transfer.api_client import get_ca ca_certs = get_ca(HOST) if username is None: print "GO Username: "******"GO Password: "******"Content-type": "application/x-www-form-urlencoded", "Hostname": HOST } c = VerifiedHTTPSConnection(HOST, PORT, ca_certs=ca_certs) body = urllib.urlencode(dict(username=username, password=password)) c.request("POST", PATH, body=body, headers=headers) response = c.getresponse() set_cookie_header = response.getheader("set-cookie") if not set_cookie_header: # TODO: more appropriate exc type raise ValueError("No cookies received") cookies = BaseCookie(set_cookie_header) morsel = cookies.get("saml") if not morsel: raise ValueError("No saml cookie received") return GOAuthResult(username, password, morsel.coded_value)
def unset_cookie(self, key): existing = self.headers.get_all('Set-Cookie') if not existing: raise KeyError('No cookies have been set') del self.headers['Set-Cookie'] found = False for header in existing: cookies = BaseCookie() cookies.load(header) if key in cookies: found = True del cookies[key] header = cookies.output(header='').lstrip() if header: if header.endswith(';'): header = header[:-1] self.headers.add_header('Set-Cookie', header) if not found: raise KeyError('No cookie has been set with the name %r' % key)
def get_go_auth(ca_certs, username=None, password=None): """ POST the login form to www.globusonline.org to get the cookie, prompting for username and password on stdin if they were not passed as parameters. @return: a GOAuthResult instance. The cookie is what most clients will be interested in, but if the username is not passed as a parameter the caller may need that as well, and may want to cache the password. """ if username is None: print "GO Username: "******"GO Password: "******"Content-type": "application/x-www-form-urlencoded", "Hostname": HOST } c = VerifiedHTTPSConnection(HOST, PORT, ca_certs=ca_certs) body = urllib.urlencode(dict(username=username, password=password)) c.request("POST", PATH, body=body, headers=headers) response = c.getresponse() set_cookie_header = response.getheader("set-cookie") if not set_cookie_header: # TODO: more appropriate exc type raise ValueError("No cookies received") cookies = BaseCookie(set_cookie_header) morsel = cookies.get("saml") if not morsel: raise ValueError("No saml cookie received") return GOAuthResult(username, password, morsel.coded_value)
def __init__(self, env): """Create request object from env.""" self._env = env self._env['REQUEST_METHOD'] = self._env['REQUEST_METHOD'].upper() # Load the query params and form params self._query = {} self._query.update(env.get('GET')) self._query.update(env.get('POST', {})) # Load the cookies self._cookies = dict2() for cookie in BaseCookie(env.get('HTTP_COOKIE')).values(): self._cookies[cookie.key] = cookie.value
def set_cookie(self, key, value='', max_age=None, path='/', domain=None, secure=None, httponly=False, version=None, comment=None, expires=None, overwrite=False): """ Set (add) a cookie for the response """ if isinstance(value, unicode) and self.charset is not None: value = '"%s"' % value.encode(self.charset) if overwrite: self.unset_cookie(key, strict=False) cookies = BaseCookie() cookies[key] = value if isinstance(max_age, timedelta): max_age = max_age.seconds + max_age.days * 24 * 60 * 60 if max_age is not None and expires is None: expires = datetime.utcnow() + timedelta(seconds=max_age) if isinstance(expires, timedelta): expires = datetime.utcnow() + expires if isinstance(expires, datetime): expires = '"' + datetime_utils._serialize_cookie_date( expires) + '"' for var_name, var_value in [ ('max-age', max_age), ('path', path), ('domain', domain), ('secure', secure), ('HttpOnly', httponly), ('version', version), ('comment', comment), ('expires', expires), ]: if var_value is not None and var_value is not False: cookies[key][var_name] = str(var_value) self._add_cookie(cookies)
def __init__(self, app, request=None, response=None, cookies=None, history=None, validate_wsgi=False): # TODO: Make validate_wsgi pass if validate_wsgi: app = wsgi_validator(app) self.app = app self.request = request self.response = response self._elements = [] # Stores file upload field values in forms self.file_uploads = {} if cookies: self.cookies = cookies else: self.cookies = BaseCookie() if response: self.cookies.update(parse_cookies(response)) if history: self.history = history else: self.history = []
def SetUserInfoCookie(key, value='', max_age=None, path='/', domain=None, secure=None, httponly=False, version=None, comment=None): cookies = BaseCookie() cookies[key] = value for var_name, var_value in [ ('max_age', max_age), ('path', path), ('domain', domain), ('secure', secure), ('HttpOnly', httponly), ('version', version), ('comment', comment), ]: if var_value is not None and var_value is not False: cookies[key][var_name.replace('_', '-')] = str(var_value) header_value = cookies[key].output(header='').lstrip() return header_value
class TestAgent(object): """ A ``TestAgent`` object provides a user agent for the WSGI application under test. Key methods and properties: - ``get(path)``, ``post(path)``, ``post_multipart`` - create get/post requests for the WSGI application and return a new ``TestAgent`` object - ``request``, ``response`` - the `werkzeug` request and response objects associated with the last WSGI request. - ``body`` - the body response as a string - ``lxml`` - the lxml representation of the response body (only applicable for HTML responses) - ``reset()`` - reset the TestAgent object to its initial state, discarding any form field values - ``find()`` (or dictionary-style attribute access) - evalute the given xpath expression against the current response body and return a list. """ response_class = wz.Response _lxml= None environ_defaults = { 'SCRIPT_NAME': "", 'PATH_INFO': "", 'QUERY_STRING': "", 'SERVER_NAME': "localhost", 'SERVER_PORT': "80", 'SERVER_PROTOCOL': "HTTP/1.0", 'REMOTE_ADDR': '127.0.0.1', 'wsgi.version': (1, 0), 'wsgi.url_scheme': 'http', 'wsgi.multithread': False, 'wsgi.multiprocess': False, 'wsgi.run_once': False, } def __init__(self, app, request=None, response=None, cookies=None, history=None, validate_wsgi=False): # TODO: Make validate_wsgi pass if validate_wsgi: app = wsgi_validator(app) self.app = app self.request = request self.response = response self._elements = [] # Stores file upload field values in forms self.file_uploads = {} if cookies: self.cookies = cookies else: self.cookies = BaseCookie() if response: self.cookies.update(parse_cookies(response)) if history: self.history = history else: self.history = [] @classmethod def make_environ(cls, REQUEST_METHOD='GET', PATH_INFO='', wsgi_input='', **kwargs): SCRIPT_NAME = kwargs.pop('SCRIPT_NAME', cls.environ_defaults["SCRIPT_NAME"]) if SCRIPT_NAME and SCRIPT_NAME[-1] == "/": SCRIPT_NAME = SCRIPT_NAME[:-1] PATH_INFO = "/" + PATH_INFO if not SCRIPT_NAME: assert not PATH_INFO.startswith('.') environ = cls.environ_defaults.copy() environ.update(kwargs) for key, value in kwargs.items(): environ[key.replace('wsgi_', 'wsgi.')] = value if isinstance(wsgi_input, basestring): wsgi_input = StringIO(wsgi_input) environ.update({ 'REQUEST_METHOD': REQUEST_METHOD, 'SCRIPT_NAME': SCRIPT_NAME, 'PATH_INFO': PATH_INFO, 'wsgi.input': wsgi_input, 'wsgi.errors': StringIO(), }) if environ['SCRIPT_NAME'] == '/': environ['SCRIPT_NAME'] = '' environ['PATH_INFO'] = '/' + environ['PATH_INFO'] while PATH_INFO.startswith('//'): PATH_INFO = PATH_INFO[1:] return environ def _request(self, environ, follow=False, history=False, status=None): path = environ['SCRIPT_NAME'] + environ['PATH_INFO'] environ['HTTP_COOKIE'] = '; '.join( '%s=%s' % (key, morsel.value) for key, morsel in self.cookies.items() if path.startswith(morsel['path']) ) if '?' in environ['PATH_INFO']: environ['PATH_INFO'], querystring = environ['PATH_INFO'].split('?', 1) if environ.get('QUERY_STRING'): environ['QUERY_STRING'] += querystring else: environ['QUERY_STRING'] = querystring if history: history = self.history + [self] else: history = self.history response = self.response_class.from_app(self.app, environ) agent = self.__class__(self.app, wz.Request(environ), response, self.cookies, history, validate_wsgi=False) if status and (status != response.status): raise BadResponse(response.status, status) if response.status == "404 NOT FOUND": if not status == response.status: raise PageNotFound(path) if follow: return agent.follow_all() return agent def get(self, PATH_INFO='/', data=None, charset='UTF-8', follow=False, history=True, status=None, **kwargs): """ Make a GET request to the application and return the response. """ if data is not None: kwargs.setdefault('QUERY_STRING', wz.url_encode(data, charset=charset, separator='&')) if self.request: PATH_INFO = uri_join_same_server(self.request.url, PATH_INFO) return self._request( self.make_environ('GET', PATH_INFO=PATH_INFO, **kwargs), follow, history, status=status, ) def post(self, PATH_INFO='/', data=None, charset='UTF-8', follow=False, history=True, status=None, **kwargs): """ Make a POST request to the application and return the response. """ if data is None: data = [] if self.request: PATH_INFO = uri_join_same_server(self.request.url, PATH_INFO) data = wz.url_encode(data, charset=charset, separator='&') wsgi_input = StringIO(data) wsgi_input.seek(0) return self._request( self.make_environ( 'POST', PATH_INFO=PATH_INFO, CONTENT_TYPE="application/x-www-form-urlencoded", CONTENT_LENGTH=str(len(data)), wsgi_input=wsgi_input, **kwargs ), follow, history, status=status, ) def post_multipart(self, PATH_INFO='/', data=None, files=None, charset='UTF-8', follow=False, **kwargs): """ Create a MockWSGI configured to post multipart/form-data to the given URI. This is usually used for mocking file uploads data dictionary of post data files list of ``(name, filename, content_type, data)`` tuples. ``data`` may be either a byte string, iterator or file-like object. """ if data is None: data = {} if files is None: files = [] if self.request: PATH_INFO = uri_join_same_server(self.request.url, PATH_INFO) boundary = '----------------------------------------BoUnDaRyVaLuE' def add_headers(key, value): """ Return a tuple of ``([(header-name, header-value), ...], data)`` for the given key/value pair """ if isinstance(value, tuple): filename, content_type, data = value headers = [ ('Content-Disposition', 'form-data; name="%s"; filename="%s"' % (key, filename)), ('Content-Type', content_type) ] return headers, data else: if isinstance(value, unicode): value = value.encode(charset) headers = [ ('Content-Disposition', 'form-data; name="%s"' % (key,)) ] return headers, value items = itertools.chain( (add_headers(k, v) for k, v in data), (add_headers(k, (fname, ctype, data)) for k, fname, ctype, data in files), ) CRLF = '\r\n' post_data = StringIO() post_data.write('--' + boundary) for headers, data in items: post_data.write(CRLF) for name, value in headers: post_data.write('%s: %s%s' % (name, value, CRLF)) post_data.write(CRLF) if hasattr(data, 'read'): copyfileobj(data, post_data) elif isinstance(data, str): post_data.write(data) else: for chunk in data: post_data.write(chunk) post_data.write(CRLF) post_data.write('--' + boundary) post_data.write('--' + CRLF) length = post_data.tell() post_data.seek(0) kwargs.setdefault('CONTENT_LENGTH', str(length)) return self._request( self.make_environ( 'POST', PATH_INFO, CONTENT_TYPE='multipart/form-data; boundary=%s' % boundary, wsgi_input=post_data, **kwargs ), follow=follow, ) def start_response(self, status, headers, exc_info=None): """ No-op implementation. """ def __str__(self): if self.response: return str(self.response) else: return super(TestAgent, self).__str__() @property def status(self): return self.response.status @property def body(self): return self.response.data @property def lxml(self): if self._lxml is not None: return self._lxml self.reset() return self._lxml def html(self, encoding=unicode): """ Return a HTML representation of the element. Defaults to returning unicode """ return lxml.html.tostring(self.lxml, encoding=encoding) def pretty(self, encoding=unicode): """ Return an pretty-printed unicode representation of the element """ return lxml.html.tostring(self.lxml, pretty_print=True, encoding=encoding) @property def root_element(self): return ElementWrapper(self, self.lxml) def reset(self): """ Reset the lxml document, abandoning any changes made """ if not self.response: raise NoRequestMadeError for element in self._elements: element.reset() self._lxml = browserify( lxml.html.fromstring( self.response.data.decode('utf-8'))) def _find(self, path, namespaces=None, css=False, **kwargs): """ Return elements matching the given xpath expression. For convenience that the EXSLT regular expression namespace (``http://exslt.org/regular-expressions``) is prebound to the prefix ``re``. """ if css: selector = CSSSelector(path) return selector(self.lxml) ns = {'re': REGEXP_NAMESPACE} if namespaces is not None: ns.update(namespaces) namespaces = ns result = self.lxml.xpath(path, namespaces=namespaces, **kwargs) return result def one(self, path, css=False, **kwargs): """ Returns the first result from Agent.all. Raises an error if more than one result is found. """ elements = self.all(path, css=css, **kwargs) if len(elements) > 1: raise MultipleMatchesError(path.encode('utf8'), elements, kwargs) elif len(elements) == 0: raise NoMatchesError(path.encode('utf8'), kwargs) else: return elements[0] def all(self, path, css=False, **kwargs): """ Returns the results of Agent.find, or Agent._findcss if css is True """ elements = self._find(path, css=css, **kwargs) return [ElementWrapper(self, el) for el in elements] @property def form(self): """ Returns a form if there is only one on the page. It is an error otherwise """ return self.one(u'//form') def click(self, path=None, follow=False, many=False, **kwargs): if not path: path = _path_from_kwargs('a', **kwargs) if many: return self.all(path)[0].click(follow=follow) else: return self.one(path).click(follow=follow) def _click(self, element, follow=False): href = element.attrib['href'] if '#' in href: href = href.split('#')[0] return self.get(href, follow=follow) def follow(self): """ If response has a ``30x`` status code, fetch (``GET``) the redirect target. No entry is recorded in the agent's history list. """ if not (300 <= int(self.response.status.split()[0]) < 400): raise AssertionError( "Can't follow non-redirect response (got %s for %s %s)" % ( self.response.status, self.request.method, self.request.path, ) ) return self.get( self.response.headers.get('Location'), history=False, ) def follow_all(self): """ If response has a ``30x`` status code, fetch (``GET``) the redirect target, until a non-redirect code is received. No entries are recorded in the agent's history list. """ agent = self while True: try: agent = agent.follow() except AssertionError: return agent def back(self, count=1): return self.history[-abs(count)] def __enter__(self): """ Provde support for context blocks """ return self def __exit__(self, exc_type, exc_value, traceback): """ At end of context block, reset the lxml document """ self.reset()
def extract_session(self, response): if "Set-Cookie" in response.headers: from Cookie import BaseCookie cookie = BaseCookie() cookie.load(response.headers["Set-Cookie"]) self.session = cookie["session"]
def __init__(self): self._content = 'None' self._content_length = None self._cookies = BaseCookie() self._headers = {HttpResponseHeaders.CONTENT_TYPE: 'text/html'} self._status_code = HttpStatusCodes.HTTP_200
class Response(object): __slots__ = [ '_content', '_content_length', '_cookies', '_headers', '_status_code' ] def __init__(self): self._content = 'None' self._content_length = None self._cookies = BaseCookie() self._headers = {HttpResponseHeaders.CONTENT_TYPE: 'text/html'} self._status_code = HttpStatusCodes.HTTP_200 def set_status(self, status_code): """Set status code for the response. Args: status_code (:obj:`str`): HTTP status See Also: :class:`drongo.status_codes.HttpStatusCodes` """ self._status_code = status_code def set_header(self, key, value): """Set a response header. Args: key (:obj:`str`): Header name value (:obj:`str`): Header value See Also: :class:`drongo.response_headers.HttpResponseHeaders` """ self._headers[key] = value def set_cookie(self, key, value, domain=None, path='/', secure=False, httponly=True): """Set a cookie. Args: key (:obj:`str`): Cookie name value (:obj:`str`): Cookie value domain (:obj:`str`): Cookie domain path (:obj:`str`): Cookie value secure (:obj:`bool`): True if secure, False otherwise httponly (:obj:`bool`): True if it's a HTTP only cookie, False otherwise """ self._cookies[key] = value if domain: self._cookies[key]['domain'] = domain if path: self._cookies[key]['path'] = path if secure: self._cookies[key]['secure'] = secure if httponly: self._cookies[key]['httponly'] = httponly def set_content(self, content, content_length=None): """Set content for the response. Args: content (:obj:`str` or :obj:`iterable`): Response content. Can be either unicode or raw bytes. When returning large content, an iterable (or a generator) can be used to avoid loading entire content into the memory. content_length (:obj:`int`, optional): Content length. Length will be determined if not set. If content is an iterable, it's a good practise to set the content length. """ if content_length is not None: self._content_length = content_length self._content = content def bake(self, start_response): """Bakes the response and returns the content. Args: start_response (:obj:`callable`): Callback method that accepts status code and a list of tuples (pairs) containing headers' key and value respectively. """ if isinstance(self._content, six.text_type): self._content = self._content.encode('utf8') if self._content_length is None: self._content_length = len(self._content) self._headers[HttpResponseHeaders.CONTENT_LENGTH] = \ str(self._content_length) headers = list(self._headers.items()) cookies = [(HttpResponseHeaders.SET_COOKIE, v.OutputString()) for _, v in self._cookies.items()] if len(cookies): headers = list(headers) + cookies start_response(self._status_code, headers) if isinstance(self._content, six.binary_type): return [self._content] return self._content # Helper functions def set_redirect(self, url, status=HttpStatusCodes.HTTP_303): """Helper method to set a redirect response. Args: url (:obj:`str`): URL to redirect to status (:obj:`str`, optional): Status code of the response """ self.set_status(status) self.set_content('') self.set_header(HttpResponseHeaders.LOCATION, url) def set_json(self, obj, status=HttpStatusCodes.HTTP_200): """Helper method to set a JSON response. Args: obj (:obj:`object`): JSON serializable object status (:obj:`str`, optional): Status code of the response """ obj = json.dumps(obj, sort_keys=True, default=lambda x: str(x)) self.set_status(status) self.set_header(HttpResponseHeaders.CONTENT_TYPE, 'application/json') self.set_content(obj)
def get(self): user = users.get_current_user() if user: self.response.out.write('''<!DOCTYPE html> <html> <head> <title>Authorized</title> <script language="Javascript" type="text/javascript"> //<![CDATA[ if (window.opener && !window.opener.closed) { window.opener.location.href = window.opener.location.href; } if (window.parent) { window.parent.location.href = window.parent.location.href; } window.close(); //]]> </script> </head> <body> </body> </html>''') return openid_url = self.request.get('openid_url', None) if openid_url is None or len(openid_url.strip()) == 0: openid_url = ID_PROVIDERS.get(self.request.get('provider'), None) if openid_url is not None: c = BaseCookie() c['idprovider'] = openid_url c['idprovider']['Max-Age'] = '2592000' self.response.headers.add_header('Set-Cookie', c.output(header="")) self.redirect( users.create_login_url(self.request.url, federated_identity=openid_url)) return else: self.response.out.write('''<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>What's Your OpenID URL</title> <!--[if lt IE 9]> <script src="/static/js/IE9.js" type="text/javascript"></script><![endif]--> <style type="text/css"> html, body, h1, h2, form, fieldset, legend, ol, li { margin: 0; padding: 0; } body { background: #ffffff; color: #111111; padding: 20px; font-family: Calibri,sans-serif; } .panel {text-align: center; padding: 3px;border-radius: 15px;background: #eeeeee; margin:150px 100px 0 100px;} .formheader {text-align: left; margin-left:65px;font-size:125%; color: #555555;padding:0} .formheader a{font-size: small;color:#888888;} #openid_url{background:url(/static/image/openid.png) no-repeat #FFF 2px; font-size: 16px; font-family: Calibri,sans-serif; padding-left:26px; width: 350px; height: 24px} button {font-size: 16px; margin:10px} </style> </head> <body> <form id="provider" method="post" name="provider"> <div class="panel"> <div class="formheader">Sign in with OpenID <a href="http://openid.net/get-an-openid/what-is-openid/" target="_blank">What is OpenID</a></div> <input id="openid_url" name="openid_url" type="text" placeholder="Please Enter Your OpenID" autocapitalize="off" autocorrect="off" required autofocus/> <button type="submit">Sign in</button> </div> </form> </body> </html> ''')
def do_request(self, req, status, expect_errors): """ Executes the given request (``req``), with the expected ``status``. Generally ``.get()`` and ``.post()`` are used instead. To use this:: resp = app.do_request(webtest.TestRequest.blank( 'url', ...args...)) Note you can pass any keyword arguments to ``TestRequest.blank()``, which will be set on the request. These can be arguments like ``content_type``, ``accept``, etc. """ __tracebackhide__ = True errors = StringIO() req.environ['wsgi.errors'] = errors if self.cookies: cookie_header = ''.join([ '%s="%s"; ' % (name, cookie_quote(value)) for name, value in self.cookies.items()]) req.environ['HTTP_COOKIE'] = cookie_header req.environ['paste.testing'] = True req.environ['paste.testing_variables'] = {} app = lint.middleware(self.app) old_stdout = sys.stdout out = CaptureStdout(old_stdout) try: sys.stdout = out start_time = time.time() ## FIXME: should it be an option to not catch exc_info? res = req.get_response(app, catch_exc_info=True) end_time = time.time() finally: sys.stdout = old_stdout res.app = app res.test_app = self # We do this to make sure the app_iter is exausted: res.body res.errors = errors.getvalue() total_time = end_time - start_time for name, value in req.environ['paste.testing_variables'].items(): if hasattr(res, name): raise ValueError( "paste.testing_variables contains the variable %r, but " "the response object already has an attribute by that " "name" % name) setattr(res, name, value) if not expect_errors: self._check_status(status, res) self._check_errors(res) res.cookies_set = {} for header in res.headers.getall('set-cookie'): try: c = BaseCookie(header) except CookieError, e: raise CookieError( "Could not parse cookie header %r: %s" % (header, e)) for key, morsel in c.items(): self.cookies[key] = morsel.value res.cookies_set[key] = morsel.value
def wsgi_app(self, environ, start_response): ctx = self.request_context(environ) ctx.push() req = ctx.request charset = req.charset session = ctx.session inner_ctx = ctx should_proxy = self.get_logged_in(session) environ['flask_protector_app.verify_login'] = partial(self.verify_login, session=session) environ['flask_protector_app.set_logged_in'] = partial(self.set_logged_in, session) environ['flask_protector_app.get_logged_in'] = partial(self.get_logged_in, session) environ['flask_protector_app.get_logged_in_as'] = partial(self.get_logged_in_as, session) new_environ = environ.copy() if should_proxy: if 'HTTP_COOKIE' in new_environ: # Scrub the environment of any trace of the protector's cookie, # because otherwise the inner app will see it and probably try # to send Set-Cookie headers to refresh the session, effectively undoing # any changes the protector wants to make to it. parsed_cookie = BaseCookie() parsed_cookie.load(environ['HTTP_COOKIE']) # TODO encoding? del parsed_cookie[self.session_cookie_name] stringified_cookie = str(parsed_cookie).partition('Set-Cookie: ')[2] if stringified_cookie: new_environ['HTTP_COOKIE'] = stringified_cookie else: del new_environ['HTTP_COOKIE'] inner_ctx = type(ctx)( self.wrapped_app, environ=new_environ, request=self.wrapped_app.request_class(new_environ) ) error = None try: response = None try: if should_proxy: inner_ctx.push() if not should_proxy: response = self.full_dispatch_request() except Exception as e: error = e response = self.handle_exception(e) except: error = sys.exc_info()[1] raise if response is not None: return response(new_environ, start_response) finally: if self.should_ignore_error(error): error = None if should_proxy: result = self.wrapped_app.wsgi_app(new_environ, start_response) inner_ctx.auto_pop(error) return result ctx.auto_pop(error)
def get(self): user = users.get_current_user() if user: self.response.out.write('''<!DOCTYPE html> <html> <head> <title>Authorized</title> <script language="Javascript" type="text/javascript"> //<![CDATA[ if (window.opener && !window.opener.closed) { window.opener.location.href = window.opener.location.href; } if (window.parent) { window.parent.location.href = window.parent.location.href; } window.close(); //]]> </script> </head> <body> </body> </html>''') return openid_url = self.request.get('openid_url', None) if openid_url is None or len(openid_url.strip()) == 0: openid_url = ID_PROVIDERS.get(self.request.get('provider'), None) if openid_url is not None: c = BaseCookie() c['idprovider'] = openid_url c['idprovider']['Max-Age'] = '2592000' self.response.headers.add_header('Set-Cookie', c.output(header="")) self.redirect(users.create_login_url(self.request.url, federated_identity = openid_url)) return else: self.response.out.write('''<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>What's Your OpenID URL</title> <!--[if lt IE 9]> <script src="/static/js/IE9.js" type="text/javascript"></script><![endif]--> <style type="text/css"> html, body, h1, h2, form, fieldset, legend, ol, li { margin: 0; padding: 0; } body { background: #ffffff; color: #111111; padding: 20px; font-family: Calibri,sans-serif; } .panel {text-align: center; padding: 3px;border-radius: 15px;background: #eeeeee; margin:150px 100px 0 100px;} .formheader {text-align: left; margin-left:65px;font-size:125%; color: #555555;padding:0} .formheader a{font-size: small;color:#888888;} #openid_url{background:url(/static/image/openid.png) no-repeat #FFF 2px; font-size: 16px; font-family: Calibri,sans-serif; padding-left:26px; width: 350px; height: 24px} button {font-size: 16px; margin:10px} </style> </head> <body> <form id="provider" method="post" name="provider"> <div class="panel"> <div class="formheader">Sign in with OpenID <a href="http://openid.net/get-an-openid/what-is-openid/" target="_blank">What is OpenID</a></div> <input id="openid_url" name="openid_url" type="text" placeholder="Please Enter Your OpenID" autocapitalize="off" autocorrect="off" required autofocus/> <button type="submit">Sign in</button> </div> </form> </body> </html> ''')