You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by jp...@apache.org on 2010/02/20 21:33:00 UTC

svn commit: r912218 [3/11] - in /incubator/chemistry/trunk/cmislib: ./ src/ src/cmislib.egg-info/ src/cmislib/ src/data/ src/doc/ src/doc/src/ src/doc/src/.doctrees/ src/doc/src/_static/ src/tests/

Added: incubator/chemistry/trunk/cmislib/src/cmislib/net.py
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/cmislib/src/cmislib/net.py?rev=912218&view=auto
==============================================================================
--- incubator/chemistry/trunk/cmislib/src/cmislib/net.py (added)
+++ incubator/chemistry/trunk/cmislib/src/cmislib/net.py Sat Feb 20 20:32:57 2010
@@ -0,0 +1,228 @@
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+#   Authors:
+#    Jeff Potts, Optaros
+#
+'''
+Module that knows how to connect to the AtomPub Binding of a CMIS repo
+'''
+
+from urllib import urlencode
+from urllib2 import HTTPBasicAuthHandler, \
+                    HTTPPasswordMgrWithDefaultRealm, \
+                    HTTPRedirectHandler, \
+                    HTTPDefaultErrorHandler, \
+                    HTTPError, \
+                    Request, \
+                    build_opener
+
+
+class SmartRedirectHandler(HTTPRedirectHandler):
+
+    """ Handles 301 and 302 redirects """
+
+    def http_error_301(self, req, fp, code, msg, headers):
+        """ Handle a 301 error """
+        result = HTTPRedirectHandler.http_error_301(
+            self, req, fp, code, msg, headers)
+        result.status = code
+        return result
+
+    def http_error_302(self, req, fp, code, msg, headers):
+        """ Handle a 302 error """
+        result = HTTPRedirectHandler.http_error_302(
+            self, req, fp, code, msg, headers)
+        result.status = code
+        return result
+
+
+class DefaultErrorHandler(HTTPDefaultErrorHandler):
+
+    """ Default error handler """
+
+    def http_error_default(self, req, fp, code, msg, headers):
+        """Provide an implementation for the default handler"""
+        result = HTTPError(
+            req.get_full_url(), code, msg, headers, fp)
+        result.status = code
+        return result
+
+
+class RESTService(object):
+
+    """
+    Generic service for interacting with an HTTP end point. Sets headers
+    such as the USER_AGENT and builds the basic auth handler.
+    """
+
+    def __init__(self):
+        self.user_agent = 'cmislib/%s +http://code.google.com/p/cmislib/'
+
+    def get(self,
+            url,
+            username=None,
+            password=None,
+            **kwargs):
+
+        """ Makes a get request to the URL specified."""
+
+        if kwargs:
+            if url.find('?') >= 0:
+                url = url + '&' + urlencode(kwargs)
+            else:
+                url = url + '?' + urlencode(kwargs)
+
+        request = RESTRequest(url, method='GET')
+
+        # add a user-agent
+        request.add_header('User-Agent', self.user_agent)
+
+        # create a password manager
+        passwordManager = HTTPPasswordMgrWithDefaultRealm()
+        passwordManager.add_password(None, url, username, password)
+
+        opener = build_opener(SmartRedirectHandler(),
+                                      DefaultErrorHandler(),
+                                      HTTPBasicAuthHandler(passwordManager))
+
+        return opener.open(request)
+
+    def delete(self, url, username=None, password=None, **kwargs):
+
+        """ Makes a delete request to the URL specified. """
+
+        if kwargs:
+            if url.find('?') >= 0:
+                url = url + '&' + urlencode(kwargs)
+            else:
+                url = url + '?' + urlencode(kwargs)
+
+        request = RESTRequest(url, method='DELETE')
+
+        # add a user-agent
+        request.add_header('User-Agent', self.user_agent)
+
+        # create a password manager
+        passwordManager = HTTPPasswordMgrWithDefaultRealm()
+        passwordManager.add_password(None, url, username, password)
+
+        opener = build_opener(SmartRedirectHandler(),
+                                      DefaultErrorHandler(),
+                                      HTTPBasicAuthHandler(passwordManager))
+
+        #try:
+        #    opener.open(request)
+        #except urllib2.HTTPError, e:
+        #    if e.code is not 204:
+        #        raise e
+        #return None
+        return opener.open(request)
+
+    def put(self,
+            url,
+            payload,
+            contentType,
+            username=None,
+            password=None,
+            **kwargs):
+
+        """
+        Makes a PUT request to the URL specified and includes the payload
+        that gets passed in. The content type header gets set to the
+        specified content type.
+        """
+
+        if kwargs:
+            if url.find('?') >= 0:
+                url = url + '&' + urlencode(kwargs)
+            else:
+                url = url + '?' + urlencode(kwargs)
+
+        request = RESTRequest(url, payload, method='PUT')
+
+        # set the content type header
+        request.add_header('Content-Type', contentType)
+
+        # add a user-agent
+        request.add_header('User-Agent', self.user_agent)
+        # create a password manager
+        passwordManager = HTTPPasswordMgrWithDefaultRealm()
+        passwordManager.add_password(None, url, username, password)
+
+        opener = build_opener(SmartRedirectHandler(),
+                                      DefaultErrorHandler(),
+                                      HTTPBasicAuthHandler(passwordManager))
+
+        return opener.open(request)
+
+    def post(self,
+             url,
+             payload,
+             contentType,
+             username=None,
+             password=None,
+             **kwargs):
+
+        """
+        Makes a POST request to the URL specified and posts the payload
+        that gets passed in. The content type header gets set to the
+        specified content type.
+        """
+
+        if kwargs:
+            if url.find('?') >= 0:
+                url = url + '&' + urlencode(kwargs)
+            else:
+                url = url + '?' + urlencode(kwargs)
+
+        request = RESTRequest(url, payload, method='POST')
+
+        # set the content type header
+        request.add_header('Content-Type', contentType)
+
+        # add a user-agent
+        request.add_header('User-Agent', self.user_agent)
+
+        # create a password manager
+        passwordManager = HTTPPasswordMgrWithDefaultRealm()
+        passwordManager.add_password(None, url, username, password)
+
+        opener = build_opener(SmartRedirectHandler(),
+                                      DefaultErrorHandler(),
+                                      HTTPBasicAuthHandler(passwordManager))
+
+        try:
+            return opener.open(request)
+        except HTTPError, e:
+            if e.code is not 201:
+                return e
+            else:
+                return e.read()
+
+
+class RESTRequest(Request):
+
+    """
+    Overrides urllib's request default behavior
+    """
+
+    def __init__(self, *args, **kwargs):
+        """ Constructor """
+        self._method = kwargs.pop('method', 'GET')
+        assert self._method in ['GET', 'POST', 'PUT', 'DELETE']
+        Request.__init__(self, *args, **kwargs)
+
+    def get_method(self):
+        """ Override the get method """
+        return self._method