manage http response headers much of this module is redhandedly pilfered from email message in the stdlib so portions are c 2001 2002 python software foundation and were written by barry warsaw regular expression that matches special characters in parameters the existence of which force quoting of the parameter value convenience function to format and return a keyvalue pair this will quote the value if needed or if quote is true manage a collection of http response headers def initself headersnone headers headers if headers is not none else if typeheaders is not list raise typeerrorheaders must be a list of namevalue tuples self headers headers if debug for k v in headers self convertstringtypek self convertstringtypev def convertstringtypeself value return the total number of headers including duplicates return lenself headers def setitemself name val delete all occurrences of a header if present does not raise an exception if the header is missing get the first header value for name return none if the header is missing instead of raising an exception note that if the header appeared multiple times the first exactly which occurrence gets returned is undefined use getall to get all the values matching a header field name return true if the message contains the header return self getname is not none def getallself name name self convertstringtypename lower return kv1 for kv in self headers if kv0 lowername def getself name defaultnone return a list of all the header field names these will be sorted in the order they appeared in the original header list or were added to this instance and may contain duplicates any fields deleted and reinserted are always appended to the header list return a list of all header values these will be sorted in the order they appeared in the original header list or were added to this instance and may contain duplicates any fields deleted and reinserted are always appended to the header list get all the header fields and values these will be sorted in the order they were in the original header list or were added to this instance and may contain duplicates any fields deleted and reinserted are always appended to the header list str returns the formatted headers complete with end line suitable for direct http transmission return rn joins s kv for kv in self headers def bytesself return strself encode iso88591 def setdefaultself name value extended header setting name is the header field to add keyword arguments can be used to set additional parameters for the header field with underscores converted to dashes normally the parameter will be added as keyvalue unless value is none in which case only the key will be added example h addheader contentdisposition attachment filename bud gif note that unlike the corresponding email message method this does not handle charset language value tuples all values must be strings or none regular expression that matches special characters in parameters the existence of which force quoting of the parameter value convenience function to format and return a key value pair this will quote the value if needed or if quote is true manage a collection of http response headers convert check value type return the total number of headers including duplicates set the value of a header delete all occurrences of a header if present does not raise an exception if the header is missing get the first header value for name return none if the header is missing instead of raising an exception note that if the header appeared multiple times the first exactly which occurrence gets returned is undefined use getall to get all the values matching a header field name return true if the message contains the header return a list of all the values for the named field these will be sorted in the order they appeared in the original header list or were added to this instance and may contain duplicates any fields deleted and re inserted are always appended to the header list if no fields exist with the given name returns an empty list get the first header value for name or return default return a list of all the header field names these will be sorted in the order they appeared in the original header list or were added to this instance and may contain duplicates any fields deleted and re inserted are always appended to the header list return a list of all header values these will be sorted in the order they appeared in the original header list or were added to this instance and may contain duplicates any fields deleted and re inserted are always appended to the header list get all the header fields and values these will be sorted in the order they were in the original header list or were added to this instance and may contain duplicates any fields deleted and re inserted are always appended to the header list str returns the formatted headers complete with end line suitable for direct http transmission return first matching header value for name or value if there is no header named name add a new header with name name and value value extended header setting _name is the header field to add keyword arguments can be used to set additional parameters for the header field with underscores converted to dashes normally the parameter will be added as key value unless value is none in which case only the key will be added example h add_header content disposition attachment filename bud gif note that unlike the corresponding email message method this does not handle charset language value tuples all values must be strings or none
import re
tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]')

def _formatparam(param, value=None, quote=1):
    
    if value is not None and len(value) > 0:
        if quote or tspecials.search(value):
            value = value.replace('\\', '\\\\').replace('"', r'\"')
            return '%s="%s"' % (param, value)
        else:
            return '%s=%s' % (param, value)
    else:
        return param


class Headers:
    

    def __init__(self, headers=None):
        headers = headers if headers is not None else []
        if type(headers) is not list:
            raise TypeError("Headers must be a list of name/value tuples")
        self._headers = headers
        if __debug__:
            for k, v in headers:
                self._convert_string_type(k)
                self._convert_string_type(v)

    def _convert_string_type(self, value):
        
        if type(value) is str:
            return value
        raise AssertionError("Header names/values must be"
            " of type str (got {0})".format(repr(value)))

    def __len__(self):
        
        return len(self._headers)

    def __setitem__(self, name, val):
        
        del self[name]
        self._headers.append(
            (self._convert_string_type(name), self._convert_string_type(val)))

    def __delitem__(self,name):
        
        name = self._convert_string_type(name.lower())
        self._headers[:] = [kv for kv in self._headers if kv[0].lower() != name]

    def __getitem__(self,name):
        
        return self.get(name)

    def __contains__(self, name):
        
        return self.get(name) is not None


    def get_all(self, name):
        
        name = self._convert_string_type(name.lower())
        return [kv[1] for kv in self._headers if kv[0].lower()==name]


    def get(self,name,default=None):
        
        name = self._convert_string_type(name.lower())
        for k,v in self._headers:
            if k.lower()==name:
                return v
        return default


    def keys(self):
        
        return [k for k, v in self._headers]

    def values(self):
        
        return [v for k, v in self._headers]

    def items(self):
        
        return self._headers[:]

    def __repr__(self):
        return "%s(%r)" % (self.__class__.__name__, self._headers)

    def __str__(self):
        
        return '\r\n'.join(["%s: %s" % kv for kv in self._headers]+['',''])

    def __bytes__(self):
        return str(self).encode('iso-8859-1')

    def setdefault(self,name,value):
        
        result = self.get(name)
        if result is None:
            self._headers.append((self._convert_string_type(name),
                self._convert_string_type(value)))
            return value
        else:
            return result

    def add_header(self, _name, _value, **_params):
        
        parts = []
        if _value is not None:
            _value = self._convert_string_type(_value)
            parts.append(_value)
        for k, v in _params.items():
            k = self._convert_string_type(k)
            if v is None:
                parts.append(k.replace('_', '-'))
            else:
                v = self._convert_string_type(v)
                parts.append(_formatparam(k.replace('_', '-'), v))
        self._headers.append((self._convert_string_type(_name), "; ".join(parts)))