[Zope-Checkins] CVS: Zope3/lib/python/Zope/Publisher/Browser - AttributePublisher.py:1.2 BrowserLanguages.py:1.2 BrowserRequest.py:1.2 BrowserResponse.py:1.2 BrowserView.py:1.2 IBrowserApplicationRequest.py:1.2 IBrowserPresentation.py:1.2 IBrowserPublication.py:1.2 IBrowserPublisher.py:1.2 IBrowserRequest.py:1.2 IBrowserView.py:1.2 IVirtualHostRequest.py:1.2 __init__.py:1.2 cgi_names.py:1.2

Jim Fulton jim@zope.com
Mon, 10 Jun 2002 19:30:04 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/Publisher/Browser
In directory cvs.zope.org:/tmp/cvs-serv20468/lib/python/Zope/Publisher/Browser

Added Files:
	AttributePublisher.py BrowserLanguages.py BrowserRequest.py 
	BrowserResponse.py BrowserView.py 
	IBrowserApplicationRequest.py IBrowserPresentation.py 
	IBrowserPublication.py IBrowserPublisher.py IBrowserRequest.py 
	IBrowserView.py IVirtualHostRequest.py __init__.py 
	cgi_names.py 
Log Message:
Merged Zope-3x-branch into newly forked Zope3 CVS Tree.

=== Zope3/lib/python/Zope/Publisher/Browser/AttributePublisher.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+from IBrowserPublisher import IBrowserPublisher
+
+class AttributePublisher(object):
+
+    __implements__ = IBrowserPublisher
+
+    # Implementation methods for interface
+    # Zope.Publisher.Browser.IBrowserPublisher.
+
+    def publishTraverse(self, request, name):
+        '''See interface IBrowserPublisher'''
+
+        if name.endswith('.html'):
+            return getattr(self, name[:-5])
+
+        return getattr(self, name)
+
+    def browserDefault(self, request):
+        '''See interface IBrowserPublisher'''
+        return self, ("index.html",)


=== Zope3/lib/python/Zope/Publisher/Browser/BrowserLanguages.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+
+from Zope.I18n.IUserPreferedLanguages import IUserPreferedLanguages
+
+
+class BrowserLanguages:
+
+    __implements__ =  IUserPreferedLanguages
+
+
+    def __init__(self, request):
+        self.request = request
+
+
+    ############################################################
+    # Implementation methods for interface
+    # Zope.I18n.IUserPreferedLanguages.
+
+    def getLanguages(self):
+        '''See interface IUserPreferedLanguages'''
+
+        langs = []
+        for lang in self.request['HTTP_ACCEPT_LANGUAGE'].split(','):
+            lang = lang.strip()
+            if lang:
+                langs.append(lang.split(';')[0])
+        return langs
+
+
+    #
+    ############################################################
+
+
+
+
+


=== Zope3/lib/python/Zope/Publisher/Browser/BrowserRequest.py 1.1 => 1.2 === (479/579 lines abridged)
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+import re
+
+from cgi import FieldStorage
+from cgi_names import isCGI_NAME, hide_key
+from Zope.Publisher.Converters import get_converter
+from Zope.Publisher.HTTP.HTTPRequest import HTTPRequest
+from IBrowserPresentation import IBrowserPresentation
+
+from IBrowserRequest import IBrowserRequest
+from IBrowserPublication import IBrowserPublication
+from IBrowserApplicationRequest import IBrowserApplicationRequest
+from BrowserResponse import BrowserResponse
+
+# Flas Constants
+SEQUENCE = 1
+DEFAULT = 2
+RECORD = 4
+RECORDS = 8
+REC = 12 # RECORD|RECORDS
+EMPTY = 16
+CONVERTED = 32
+DEFAULTABLE_METHODS = 'GET', 'POST'
+
+search_type = re.compile('(:[a-zA-Z][a-zA-Z0-9_]+|\\.[xy])$').search
+
+
+class BrowserRequest(HTTPRequest):
+
+    __implements__ = (HTTPRequest.__implements__,
+                      IBrowserRequest, IBrowserPublication,
+                      IBrowserApplicationRequest,
+                      )
+

[-=- -=- -=- 479 lines omitted -=- -=- -=-]

+    use_redirect = 1
+
+class TestRequest(BrowserRequest):
+
+    def __init__(self, body_instream=None, outstream=None, environ=None, **kw):
+
+        _testEnv =  {
+            'SERVER_URL':         'http://127.0.0.1',
+            'HTTP_HOST':          '127.0.0.1',
+            'CONTENT_LENGTH':     '0',
+            'GATEWAY_INTERFACE':  'TestFooInterface/1.0',
+            }
+
+        if environ:
+            _testEnv.update(environ)
+        if kw:
+            _testEnv.update(kw)
+        if body_instream is None:
+            from StringIO import StringIO
+            body_instream = StringIO('')
+
+        if outstream is None:
+            outstream = StringIO()
+
+        super(TestRequest, self).__init__(body_instream, outstream, _testEnv)
+    
+# add class copied from Zope2
+class record:
+
+    def __getattr__(self, key, default=None):
+        if key in ('get', 'keys', 'items', 'values', 'copy',
+                   'has_key', '__contains__'):
+            return getattr(self.__dict__, key)
+        raise AttributeError, key
+
+    def __getitem__(self, key):
+        return self.__dict__[key]
+            
+    def __str__(self):
+        L1 = self.__dict__.items()
+        L1.sort()
+        return ", ".join(map(lambda item: "%s: %s" % item, L1)) 
+
+    def __repr__(self):
+        L1 = self.__dict__.items()
+        L1.sort()
+        return ', '.join(
+            map(lambda item: "%s: %s" % (item[0], repr(item[1])), L1))
+    
+


=== Zope3/lib/python/Zope/Publisher/Browser/BrowserResponse.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+'''HTTP Response Output formatter
+
+$Id$'''
+__version__='$Revision$'[11:-2]
+
+import sys, re
+from types import StringType, ClassType
+from cgi import escape
+
+from Zope.Publisher.HTTP.HTTPResponse import HTTPResponse
+from Zope.Publisher.Exceptions import Redirect
+
+
+start_of_header_search=re.compile('(<head[^>]*>)', re.IGNORECASE).search
+base_re_search=re.compile('(<base.*?>)',re.I).search
+
+
+class BrowserResponse(HTTPResponse):
+    """Browser response
+    """
+
+    __slots__ = (
+        '_base', # The base href
+        )
+
+    def setBody(self, body):
+        """Sets the body of the response
+        
+        Sets the return body equal to the (string) argument "body". Also
+        updates the "content-length" return header and sets the status to
+        200 if it has not already been set.
+        """
+        body = str(body)
+
+        if not ('content-type' in self._headers):
+            c = (self.__isHTML(body) and 'text/html' or 'text/plain')
+            self.setHeader('content-type', c)
+
+        content_type = self._headers['content-type']
+        if is_text_html(content_type):
+            # Some browsers interpret certain characters in Latin 1 as html
+            # special characters. These cannot be removed by html_quote,
+            # because this is not the case for all encodings.
+            body = body.replace('\213', '&lt;')
+            body = body.replace('\233', '&gt;')
+
+        body = self.__insertBase(body)
+        self._body = body
+        self._updateContentLength()
+        if not self._status_set:
+            self.setStatus(200)
+
+    def __isHTML(self, str):
+        s = str.strip().lower()
+        return s.startswith('<html>') or s.startswith('<!doctype html')
+
+
+    def __wrapInHTML(self, title, content):
+        t = escape(title)
+        return (
+            "<html><head><title>%s</title></head>\n"
+            "<body><h2>%s</h2>\n"
+            "%s\n"
+            "</body></html>\n" %
+            (t, t, content)
+            )
+
+
+    def __insertBase(self, body):
+        # Only insert a base tag if content appears to be html.
+        content_type = self.getHeader('content-type', '')
+        if content_type and not is_text_html(content_type):
+            return body
+
+        if getattr(self, '_base', ''):
+            if body:
+                match = start_of_header_search(body)
+                if match is not None:
+                    index = match.start(0) + len(match.group(0))
+                    ibase = base_re_search(body)
+                    if ibase is None:
+                        body = ('%s\n<base href="%s" />\n%s' %
+                                (body[:index], self._base, body[index:]))
+        return body
+
+    def getBase(self):
+        return getattr(self, '_base', '')
+
+    def setBase(self, base):
+        self._base = base
+
+
+
+latin1_alias_match = re.compile(
+    r'text/html(\s*;\s*charset=((latin)|(latin[-_]?1)|'
+    r'(cp1252)|(cp819)|(csISOLatin1)|(IBM819)|(iso-ir-100)|'
+    r'(iso[-_]8859[-_]1(:1987)?)))?$',re.I).match
+
+def is_text_html(content_type):
+    return (content_type == 'text/html' or
+            latin1_alias_match(content_type) is not None)


=== Zope3/lib/python/Zope/Publisher/Browser/BrowserView.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+__metaclass__ = type # All classes are new style when run with Python 2.2+
+
+from IBrowserView import IBrowserView
+
+class BrowserView:
+
+    __implements__ = IBrowserView
+
+    def __init__(self, context, request):
+       self.context = context
+       self.request = request
+


=== Zope3/lib/python/Zope/Publisher/Browser/IBrowserApplicationRequest.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from Zope.Publisher.HTTP.IHTTPApplicationRequest import IHTTPApplicationRequest
+from Interface.Attribute import Attribute
+
+class IBrowserApplicationRequest(IHTTPApplicationRequest):
+    """Browser-specific requests
+    """
+
+    def __getitem__(key):
+        """Return Browser request data 
+
+        Request data sre retrieved from one of:
+
+        - Environment variables
+
+          These variables include input headers, server data, and other
+          request-related data.  The variable names are as <a
+          href="http://hoohoo.ncsa.uiuc.edu/cgi/env.html">specified</a>
+          in the <a
+          href="http://hoohoo.ncsa.uiuc.edu/cgi/interface.html">CGI
+          specification</a>
+
+        - Cookies
+
+          These are the cookie data, if present.
+
+        - Form data
+
+        Form data are searched before cookies, which are searched
+        before environmental data.
+        """
+
+    form = Attribute(
+        """Form data
+
+        This is a read-only mapping from name to form value for the name.
+        """)


=== Zope3/lib/python/Zope/Publisher/Browser/IBrowserPresentation.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+from Zope.ComponentArchitecture.IPresentation import IPresentation
+
+class IBrowserPresentation(IPresentation):
+    """Browser presentations are for interaction with user's using Web Browsers
+    """
+


=== Zope3/lib/python/Zope/Publisher/Browser/IBrowserPublication.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+
+Revision information:
+$Id$
+"""
+
+from Zope.Publisher.IPublication import IPublication
+
+class IBrowserPublication (IPublication):
+    """
+    Object publication framework.
+    """
+
+    def getDefaultTraversal(request, ob):
+        """Get the default published object for the request
+        
+        Allows a default view to be added to traversal.
+        Returns (ob, steps_reversed).
+        """
+


=== Zope3/lib/python/Zope/Publisher/Browser/IBrowserPublisher.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+from Zope.Publisher.IPublishTraverse import IPublishTraverse
+
+class IBrowserPublisher(IPublishTraverse):
+
+    def browserDefault(request):
+        """Provide the default object
+
+        The default object is expressed as a (possibly different)
+        object and/or additional traversal steps.
+
+        Returns an object and a sequence of names.  If the sequence of
+        names is not empty, then a traversal step is made for each name.
+        After the publisher gets to the end of the sequence, it will
+        call browserDefault on the last traversed object.
+
+        Normal usage is to return self for object and a default view name.
+
+        The publisher calls this method at the end of each traversal path. If
+        a non-empty sequence of names is returned, the publisher will traverse 
+        those names and call browserDefault again at the end.
+
+        Note that if additional traversal steps are indicated (via a
+        nonempty sequence of names), then the publisher will try to adjust
+        the base href.
+        """
+


=== Zope3/lib/python/Zope/Publisher/Browser/IBrowserRequest.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+from Zope.Publisher.HTTP.IHTTPRequest import IHTTPRequest
+from IVirtualHostRequest import IVirtualHostRequest
+
+
+class IBrowserRequest(IHTTPRequest, IVirtualHostRequest):
+    """Browser-specific Request functionality.
+
+    Note that the browser is special in many ways, since it exposes
+    the Request object to the end-developer.
+    """


=== Zope3/lib/python/Zope/Publisher/Browser/IBrowserView.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+from Zope.ComponentArchitecture.IView import IView
+from IBrowserPresentation import IBrowserPresentation
+
+class IBrowserView(IBrowserPresentation, IView):
+    "Browser View"
+


=== Zope3/lib/python/Zope/Publisher/Browser/IVirtualHostRequest.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+"""
+
+$Id$
+"""
+
+from Interface import Interface
+
+class IVirtualHostRequest(Interface):
+    """The support for virtual hosts in Zope is very important.
+
+    In order to make virtual hosts working, we need to support several
+    methods in our Request object. This interface defines the required
+    methods.
+    """
+
+    def setVirtualRoot(path, hard=0):
+        """Treat the current publishing object as a VirtualRoot.
+        """
+
+
+    def convertPhysicalPathToVirtualPath(path):
+        """Remove the path to the VirtualRoot from a physical path.
+        """
+
+
+    def convertPhysicalPathToURL(path, relative=0):
+        """Convert a physical path into a URL in the current context.
+        """
+
+
+    def getPhysicalPathFromURL(URL):
+        """Convert a URL into a physical path in the current context.
+
+        If the URL makes no sense in light of the current virtual
+        hosting context, a ValueError is raised.
+        """
+
+    def getEffectiveURL(self):
+        """Return the effective URL.
+        """


=== Zope3/lib/python/Zope/Publisher/Browser/__init__.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################


=== Zope3/lib/python/Zope/Publisher/Browser/cgi_names.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# 
+##############################################################################
+import cgi
+if not hasattr(cgi, 'valid_boundary'):
+    try: import cgi_hotfix
+    except ImportError: pass
+
+isCGI_NAME = {
+    # These fields are placed in request.environ instead of request.form.
+    'SERVER_SOFTWARE' : 1, 
+    'SERVER_NAME' : 1, 
+    'GATEWAY_INTERFACE' : 1, 
+    'SERVER_PROTOCOL' : 1, 
+    'SERVER_PORT' : 1, 
+    'REQUEST_METHOD' : 1, 
+    'PATH_INFO' : 1, 
+    'PATH_TRANSLATED' : 1, 
+    'SCRIPT_NAME' : 1, 
+    'QUERY_STRING' : 1, 
+    'REMOTE_HOST' : 1, 
+    'REMOTE_ADDR' : 1, 
+    'AUTH_TYPE' : 1, 
+    'REMOTE_USER' : 1, 
+    'REMOTE_IDENT' : 1, 
+    'CONTENT_TYPE' : 1, 
+    'CONTENT_LENGTH' : 1,
+    'SERVER_URL': 1,
+    }.has_key
+
+hide_key={
+    'HTTP_AUTHORIZATION':1,
+    'HTTP_CGI_AUTHORIZATION': 1,
+    }.has_key
+