def set_cookie(self, name, value, domain=None, expires=None, path="/",
                   expires_days=None):
        """Sets the given cookie name/value with the given options."""
        
        name = escape.utf8(name)
        
        value = base64.b64encode(pickle.dumps(value))
        
#        if re.search(r"[\x00-\x20]", name + value):
#            # Don't let us accidentally inject bad stuff
#            raise ValueError("Invalid cookie %r: %r" % (name, value))

        if not hasattr(self, "_new_cookies"): self._new_cookies = []
        
        new_cookie = Cookie.BaseCookie()
        self._new_cookies.append(new_cookie)
        new_cookie[name] = value
        
        if domain:
            new_cookie[name]["domain"] = domain
        if expires_days is not None and not expires:
            expires = datetime.datetime.utcnow() + datetime.timedelta(
                days=expires_days)
        if expires:
            timestamp = calendar.timegm(expires.utctimetuple())
            new_cookie[name]["expires"] = email.utils.formatdate(
                timestamp, localtime=False, usegmt=True)
        if path:
            new_cookie[name]["path"] = path
 def redirect(self, url, args={}, permanent=False):
     """Sends a redirect to the given (optionally relative) URL."""
     
     if args: url += "?"+urllib.urlencode(args)
     
     if self._headers_written:
         raise Exception("Cannot redirect after headers have been written")
     self.set_status(301 if permanent else 302)
     # Remove whitespace
     url = re.sub(r"[\x00-\x20]+", "", escape.utf8(url))
     self.set_header("Location", urlparse.urljoin(self.request.uri, url))
     self.finish()
     
     # we raise so we'll branch out of where we were, without having to 
     # explicitly return.  i can't believe how many bugs were from me forgetting
     # to return after i redirected...
     raise Redirect, url
    def write(self, chunk):
        """Writes the given chunk to the output buffer.

        To write the output to the network, use the flush() method below.

        If the given chunk is a dictionary, we write it as JSON and set
        the Content-Type of the response to be text/javascript.
        """
        assert not self._finished
        if getattr(self, 'content_type', None) == 'application/json':
            chunk = escape.json_encode(chunk)
            #self.set_content_type("text/javascript; charset=UTF-8")
            self.set_content_type(self.content_type)
        
        elif hasattr(self, 'content_type'):
            self.set_content_type(self.content_type)
            
        chunk = escape.utf8(chunk)
        self._write_buffer.append(chunk)
    def set_header(self, name, value):
        """Sets the given response header name and value.

        If a datetime is given, we automatically format it according to the
        HTTP specification. If the value is not a string, we convert it to
        a string. All header values are then encoded as UTF-8.
        """
        if isinstance(value, datetime.datetime):
            t = calendar.timegm(value.utctimetuple())
            value = email.utils.formatdate(t, localtime=False, usegmt=True)
        elif isinstance(value, int) or isinstance(value, long):
            value = str(value)
        else:
            value = escape.utf8(value)
            # If \n is allowed into the header, it is possible to inject
            # additional headers or split the request. Also cap length to
            # prevent obviously erroneous values.
            safe_value = re.sub(r"[\x00-\x1f]", " ", value)[:4000]
            if safe_value != value:
                raise ValueError("Unsafe header value %r", value)
        self._headers[name] = value