示例#1
0
    def __call__(self, environ, start_response):
        realmname = self._domaincontroller.getDomainRealm(environ["PATH_INFO"], environ)
        
        if not self._domaincontroller.requireAuthentication(realmname, environ):
            # no authentication needed
            _logger.debug("No authorization required for realm '%s'" % realmname)
            environ["http_authenticator.realm"] = realmname
            environ["http_authenticator.username"] = ""
            return self._application(environ, start_response)
        
        if "HTTP_AUTHORIZATION" in environ:
            authheader = environ["HTTP_AUTHORIZATION"] 
            authmatch = self._headermethod.search(authheader)          
            authmethod = "None"
            if authmatch:
                authmethod = authmatch.group(1).lower()
                
            if authmethod == "digest" and self._acceptdigest:
                return self.authDigestAuthRequest(environ, start_response)
            elif authmethod == "digest" and self._acceptbasic:
                return self.sendBasicAuthResponse(environ, start_response)
            elif authmethod == "basic" and self._acceptbasic:
                return self.authBasicAuthRequest(environ, start_response)

            util.log("HTTPAuthenticator: respond with 400 Bad request; Auth-Method: %s" % authmethod)
            
            start_response("400 Bad Request", [("Content-Length", "0"),
                                               ("Date", util.getRfc1123Time()),
                                               ])
            return [""]
        
                                   
        if self._defaultdigest:
            return self.sendDigestAuthResponse(environ, start_response)
        return self.sendBasicAuthResponse(environ, start_response)
    def __call__(self, environ, start_response):
        path = environ["PATH_INFO"]

        davres = None
        if environ["wsgidav.provider"]:
            davres = environ["wsgidav.provider"].getResourceInst(path, environ)

        if environ["REQUEST_METHOD"] in ("GET", "HEAD") and davres and davres.isCollection:

            #            if "mozilla" not in environ.get("HTTP_USER_AGENT").lower():
            #                # issue 14: Nautilus sends GET on collections
            #                # http://code.google.com/p/wsgidav/issues/detail?id=14
            #                util.status("Directory browsing disabled for agent '%s'" % environ.get("HTTP_USER_AGENT"))
            #                self._fail(HTTP_NOT_IMPLEMENTED)
            #                return self._application(environ, start_response)

            if util.getContentLength(environ) != 0:
                self._fail(HTTP_MEDIATYPE_NOT_SUPPORTED, "The server does not handle any body content.")

            if environ["REQUEST_METHOD"] == "HEAD":
                return util.sendStatusResponse(environ, start_response, HTTP_OK)

            # Support DAV mount (http://www.ietf.org/rfc/rfc4709.txt)
            dirConfig = environ["wsgidav.config"].get("dir_browser", {})
            if dirConfig.get("davmount") and "davmount" in environ.get("QUERY_STRING"):
                #                collectionUrl = davres.getHref()
                collectionUrl = util.makeCompleteUrl(environ)
                collectionUrl = collectionUrl.split("?")[0]
                res = """
                    <dm:mount xmlns:dm="http://purl.org/NET/webdav/mount">
                        <dm:url>%s</dm:url>
                    </dm:mount>""" % (
                    collectionUrl
                )
                # TODO: support <dm:open>%s</dm:open>

                start_response(
                    "200 OK",
                    [
                        ("Content-Type", "application/davmount+xml"),
                        ("Content-Length", str(len(res))),
                        ("Cache-Control", "private"),
                        ("Date", util.getRfc1123Time()),
                    ],
                )
                return [res]

            # Profile calls
            #            if True:
            #                from cProfile import Profile
            #                profile = Profile()
            #                profile.runcall(self._listDirectory, environ, start_response)
            #                # sort: 0:"calls",1:"time", 2: "cumulative"
            #                profile.print_stats(sort=2)
            return self._listDirectory(davres, environ, start_response)

        return self._application(environ, start_response)
    def __call__(self, environ, start_response):
        path = environ["PATH_INFO"]

        davres = None
        if environ["wsgidav.provider"]:
            davres = environ["wsgidav.provider"].getResourceInst(path, environ)

        if environ["REQUEST_METHOD"] in (
                "GET", "HEAD") and davres and davres.isCollection:

            #            if "mozilla" not in environ.get("HTTP_USER_AGENT").lower():
            #                # issue 14: Nautilus sends GET on collections
            #                # http://code.google.com/p/wsgidav/issues/detail?id=14
            #                util.status("Directory browsing disabled for agent '%s'" % environ.get("HTTP_USER_AGENT"))
            #                self._fail(HTTP_NOT_IMPLEMENTED)
            #                return self._application(environ, start_response)

            if util.getContentLength(environ) != 0:
                self._fail(HTTP_MEDIATYPE_NOT_SUPPORTED,
                           "The server does not handle any body content.")

            if environ["REQUEST_METHOD"] == "HEAD":
                return util.sendStatusResponse(environ, start_response,
                                               HTTP_OK)

            # Support DAV mount (http://www.ietf.org/rfc/rfc4709.txt)
            dirConfig = environ["wsgidav.config"].get("dir_browser", {})
            if dirConfig.get("davmount") and "davmount" in environ.get(
                    "QUERY_STRING"):
                #                collectionUrl = davres.getHref()
                collectionUrl = util.makeCompleteUrl(environ)
                collectionUrl = collectionUrl.split("?")[0]
                res = """
                    <dm:mount xmlns:dm="http://purl.org/NET/webdav/mount">
                        <dm:url>%s</dm:url>
                    </dm:mount>""" % (collectionUrl)
                # TODO: support <dm:open>%s</dm:open>

                start_response("200 OK", [
                    ("Content-Type", "application/davmount+xml"),
                    ("Content-Length", str(len(res))),
                    ("Cache-Control", "private"),
                    ("Date", util.getRfc1123Time()),
                ])
                return [res]

            # Profile calls
#            if True:
#                from cProfile import Profile
#                profile = Profile()
#                profile.runcall(self._listDirectory, environ, start_response)
#                # sort: 0:"calls",1:"time", 2: "cumulative"
#                profile.print_stats(sort=2)
            return self._listDirectory(davres, environ, start_response)

        return self._application(environ, start_response)
 def sendBasicAuthResponse(self, environ, start_response):
     realmname = self._domaincontroller.getDomainRealm(environ["PATH_INFO"] , environ)
     _logger.debug("401 Not Authorized for realm '%s' (basic)" % realmname)
     wwwauthheaders = "Basic realm=\"" + realmname + "\"" 
     
     body = self.getErrorMessage()
     start_response("401 Not Authorized", [("WWW-Authenticate", wwwauthheaders),
                                           ("Content-Type", "text/html"),
                                           ("Content-Length", str(len(body))),
                                           ("Date", util.getRfc1123Time()),
                                           ])
     return [ body ]
    def __call__(self, environ, start_response):
        path = environ["PATH_INFO"]

        # We want to answer OPTIONS(*), even if no handler was registered for
        # the top-level realm (e.g. required to map drive letters).

        provider = environ["wsgidav.provider"]

        # Hotfix for WinXP / Vista: accept '/' for a '*'
        if environ["REQUEST_METHOD"] == "OPTIONS" and path in ("/", "*"):
            # Answer HTTP 'OPTIONS' method on server-level.
            # From RFC 2616:
            # If the Request-URI is an asterisk ("*"), the OPTIONS request is
            # intended to apply to the server in general rather than to a specific
            # resource. Since a server's communication options typically depend on
            # the resource, the "*" request is only useful as a "ping" or "no-op"
            # type of method; it does nothing beyond allowing the client to test the
            # capabilities of the server. For example, this can be used to test a
            # proxy for HTTP/1.1 compliance (or lack thereof).

            dav_compliance_level = "1,2"

            if provider is None or provider.isReadOnly(
            ) or provider.lockManager is None:
                dav_compliance_level = "1"

            headers = [
                ("Content-Type", "text/html; charset=UTF-8"),
                ("Content-Length", "0"),
                ("DAV", dav_compliance_level),
                ("Date", util.getRfc1123Time()),
            ]

            if environ["wsgidav.config"].get("add_header_MS_Author_Via",
                                             False):
                headers.append(("MS-Author-Via", "DAV"))

            start_response("200 OK", headers)
            yield ""
            return

        if provider is None:
            raise DAVError(HTTP_NOT_FOUND,
                           "Could not find resource provider for '%s'" % path)

        # Let the appropriate resource provider for the realm handle the request
        app = RequestServer(provider)
        app_iter = app(environ, start_response)
        for v in app_iter:
            yield v
        if hasattr(app_iter, "close"):
            app_iter.close()
        return
示例#6
0
 def sendBasicAuthResponse(self, environ, start_response):
     realmname = self._domaincontroller.getDomainRealm(environ["PATH_INFO"] , environ)
     _logger.debug("401 Not Authorized for realm '%s' (basic)" % realmname)
     wwwauthheaders = "Basic realm=\"" + realmname + "\"" 
     
     body = self.getErrorMessage()
     start_response("401 Not Authorized", [("WWW-Authenticate", wwwauthheaders),
                                           ("Content-Type", "text/html"),
                                           ("Content-Length", str(len(body))),
                                           ("Date", util.getRfc1123Time()),
                                           ])
     return [ body ]
    def __call__(self, environ, start_response):
        path = environ["PATH_INFO"]
        
        # We want to answer OPTIONS(*), even if no handler was registered for 
        # the top-level realm (e.g. required to map drive letters). 

        provider = environ["wsgidav.provider"]

        # Hotfix for WinXP / Vista: accept '/' for a '*'
        if environ["REQUEST_METHOD"] == "OPTIONS" and path in ("/", "*"):
            # Answer HTTP 'OPTIONS' method on server-level.
            # From RFC 2616:
            # If the Request-URI is an asterisk ("*"), the OPTIONS request is 
            # intended to apply to the server in general rather than to a specific 
            # resource. Since a server's communication options typically depend on 
            # the resource, the "*" request is only useful as a "ping" or "no-op" 
            # type of method; it does nothing beyond allowing the client to test the 
            # capabilities of the server. For example, this can be used to test a 
            # proxy for HTTP/1.1 compliance (or lack thereof). 
            
            dav_compliance_level = "1,2"

            if provider is None or provider.isReadOnly() or provider.lockManager is None:
                dav_compliance_level = "1"

            headers = [("Content-Type", "text/html"),
                       ("Content-Length", "0"),
                       ("DAV", dav_compliance_level),
                       ("Date", util.getRfc1123Time()),
                       ]

            if environ["wsgidav.config"].get("add_header_MS_Author_Via", False):
                headers.append( ("MS-Author-Via", "DAV") )
                
            start_response("200 OK", headers)
            yield ""        
            return
   
        if provider is None:
            raise DAVError(HTTP_NOT_FOUND,
                           "Could not find resource provider for '%s'" % path)

        # Let the appropriate resource provider for the realm handle the request
        app = RequestServer(provider)
        app_iter = app(environ, start_response)
        for v in app_iter:
            yield v
        if hasattr(app_iter, "close"):
            app_iter.close()
        return
示例#8
0
    def __call__(self, environ, start_response):
        realmname = self._domaincontroller.getDomainRealm(
            environ["PATH_INFO"], environ)

        _logger.debug("realm '%s'" % realmname)
        # _logger.debug("%s" % environ)

        force_allow = False
        if HOTFIX_WIN_AcceptAnonymousOptions and environ[
                "REQUEST_METHOD"] == "OPTIONS":
            _logger.warning("No authorization required for OPTIONS method")
            force_allow = True

        if force_allow or not self._domaincontroller.requireAuthentication(
                realmname, environ):
            # no authentication needed
            _logger.debug("No authorization required for realm '%s'" %
                          realmname)
            environ["http_authenticator.realm"] = realmname
            environ["http_authenticator.username"] = ""
            return self._application(environ, start_response)

        if "HTTP_AUTHORIZATION" in environ:
            authheader = environ["HTTP_AUTHORIZATION"]
            authmatch = self._headermethod.search(authheader)
            authmethod = "None"
            if authmatch:
                authmethod = authmatch.group(1).lower()

            if authmethod == "digest" and self._acceptdigest:
                return self.authDigestAuthRequest(environ, start_response)
            elif authmethod == "digest" and self._acceptbasic:
                return self.sendBasicAuthResponse(environ, start_response)
            elif authmethod == "basic" and self._acceptbasic:
                return self.authBasicAuthRequest(environ, start_response)

            util.log(
                "HTTPAuthenticator: respond with 400 Bad request; Auth-Method: %s"
                % authmethod)

            start_response("400 Bad Request", [
                ("Content-Length", "0"),
                ("Date", util.getRfc1123Time()),
            ])
            return [""]

        if self._defaultdigest:
            return self.sendDigestAuthResponse(environ, start_response)
        return self.sendBasicAuthResponse(environ, start_response)
    def sendDigestAuthResponse(self, environ, start_response):    
        realmname = self._domaincontroller.getDomainRealm(environ["PATH_INFO"] , environ)
        random.seed()
        serverkey = hex(random.getrandbits(32))[2:]
        etagkey = md5(environ["PATH_INFO"]).hexdigest()
        timekey = str(time.time())  
        nonce = base64.b64encode(timekey + md5(timekey + ":" + etagkey + ":" + serverkey).hexdigest())
        wwwauthheaders = "Digest realm=\"" + realmname + "\", nonce=\"" + nonce + \
            "\", algorithm=\"MD5\", qop=\"auth\""                 
        _logger.debug("401 Not Authorized for realm '%s' (digest): %s" % (realmname, wwwauthheaders))

        body = self.getErrorMessage()
#        start_response("403 Forbidden", [("WWW-Authenticate", wwwauthheaders),
        start_response("401 Not Authorized", [("WWW-Authenticate", wwwauthheaders),
                                              ("Content-Type", "text/html"),
                                              ("Content-Length", str(len(body))),
                                              ("Date", util.getRfc1123Time()),
                                              ])
        return [ body ]
示例#10
0
    def sendDigestAuthResponse(self, environ, start_response):    
        realmname = self._domaincontroller.getDomainRealm(environ["PATH_INFO"] , environ)
        random.seed()
        serverkey = hex(random.getrandbits(32))[2:]
        etagkey = md5(environ["PATH_INFO"]).hexdigest()
        timekey = str(time.time())  
        nonce = base64.b64encode(timekey + md5(timekey + ":" + etagkey + ":" + serverkey).hexdigest())
        wwwauthheaders = "Digest realm=\"" + realmname + "\", nonce=\"" + nonce + \
            "\", algorithm=\"MD5\", qop=\"auth\""                 
        _logger.debug("401 Not Authorized for realm '%s' (digest): %s" % (realmname, wwwauthheaders))

        body = self.getErrorMessage()
#        start_response("403 Forbidden", [("WWW-Authenticate", wwwauthheaders),
        start_response("401 Not Authorized", [("WWW-Authenticate", wwwauthheaders),
                                              ("Content-Type", "text/html"),
                                              ("Content-Length", str(len(body))),
                                              ("Date", util.getRfc1123Time()),
                                              ])
        return [ body ]
示例#11
0
    def __call__(self, environ, start_response):
        path = environ["PATH_INFO"]
        
        # We want to answer OPTIONS(*), even if no handler was registered for 
        # the top-level realm (e.g. required to map drive letters). 

        # Hotfix for WinXP / Vista: accept '/' for a '*'
        if environ["REQUEST_METHOD"] == "OPTIONS" and path in ("/", "*"):
            # Answer HTTP 'OPTIONS' method on server-level.
            # From RFC 2616:
            # If the Request-URI is an asterisk ("*"), the OPTIONS request is 
            # intended to apply to the server in general rather than to a specific 
            # resource. Since a server's communication options typically depend on 
            # the resource, the "*" request is only useful as a "ping" or "no-op" 
            # type of method; it does nothing beyond allowing the client to test the 
            # capabilities of the server. For example, this can be used to test a 
            # proxy for HTTP/1.1 compliance (or lack thereof). 
            start_response("200 OK", [("Content-Type", "text/html"),
                                      ("Content-Length", "0"),
                                      ("DAV", "1,2"),
                                      ("Server", "DAV/2"),
                                      ("Date", util.getRfc1123Time()),
                                      ])
            yield ""        
            return
   
        provider = environ["wsgidav.provider"]
        if provider is None:
            raise DAVError(HTTP_NOT_FOUND,
                           "Could not find resource provider for '%s'" % path)

        # Let the appropriate resource provider for the realm handle the request
        app = RequestServer(provider)
        for v in app(environ, start_response):
            yield v
        return
示例#12
0
    def _listDirectory(self, davres, environ, start_response):
        """
        @see: http://www.webdav.org/specs/rfc4918.html#rfc.section.9.4
        """
        assert davres.isCollection
        
        dirConfig = environ["wsgidav.config"].get("dir_browser", {})
        displaypath = urllib.unquote(davres.getHref())
        isReadOnly = environ["wsgidav.provider"].isReadOnly()

        trailer = dirConfig.get("response_trailer")
        if trailer:
            trailer = trailer.replace("${version}", 
                "<a href='https://github.com/mar10/wsgidav/'>WsgiDAV/%s</a>" % __version__)
            trailer = trailer.replace("${time}", util.getRfc1123Time())
        else:
            trailer = ("Seafile WebDAV Server, based on <a href='https://github.com/mar10/wsgidav/'>WsgiDAV/%s</a> - %s" 
                       % (__version__, util.getRfc1123Time()))

        
        html = []
        html.append("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>");
        html.append("<html>")
        html.append("<head>")
        html.append("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>")
        html.append("<meta name='generator' content='WsgiDAV %s'>" % __version__)
        html.append("<title>WsgiDAV - Index of %s </title>" % displaypath)
        
        html.append("<script type='text/javascript'>%s</script>" % PAGE_SCRIPT)
        html.append("<style type='text/css'>%s</style>" % PAGE_CSS)

        # Special CSS to enable MS Internet Explorer behaviour
        if dirConfig.get("ms_mount"):
            html.append("<style type='text/css'> A {behavior: url(#default#AnchorClick);} </style>")
        
        if dirConfig.get("ms_sharepoint_plugin"):
            html.append("<object id='winFirefoxPlugin' type='application/x-sharepoint' width='0' height='0' style=''visibility: hidden;'></object>")

        html.append("</head>")
        html.append("<body onload='onLoad()'>")

        # Title
        html.append("<h1>Index of %s</h1>" % displaypath)
        # Add DAV-Mount link and Web-Folder link
        links = []
        if dirConfig.get("davmount"):
            links.append("<a title='Open this folder in a WebDAV client.' href='%s?davmount'>Mount</a>" % util.makeCompleteUrl(environ))
        if dirConfig.get("ms_mount"):
            links.append("<a title='Open as Web Folder (requires Microsoft Internet Explorer)' href='' FOLDER='%s'>Open as Web Folder</a>" % util.makeCompleteUrl(environ))
#                html.append("<a href='' FOLDER='%ssetup.py'>Open setup.py as WebDAV</a>" % util.makeCompleteUrl(environ))
        if links:
            html.append("<p>%s</p>" % " &#8211; ".join(links))

        html.append("<hr>")
        # Listing
        html.append("<table onclick='return onClickTable(event)'>")

        html.append("<thead>")
        html.append("<tr><th>Name</th> <th>Type</th> <th class='right'>Size</th> <th class='right'>Last modified</th> </tr>")
        html.append("</thead>")
            
        html.append("<tbody>")
        if davres.path in ("", "/"):
            html.append("<tr><td>Top level share</td> <td></td> <td></td> <td></td> </tr>")
        else:
            parentUrl = util.getUriParent(davres.getHref())
            html.append("<tr><td><a href='" + parentUrl + "'>Parent Directory</a></td> <td></td> <td></td> <td></td> </tr>")

        # Ask collection for member info list
        dirInfoList = davres.getDirectoryInfo()

        if dirInfoList is None:
            # No pre-build info: traverse members
            dirInfoList = []
            childList = davres.getDescendants(depth="1", addSelf=False)
            for res in childList:
                di = res.getDisplayInfo()
                href = res.getHref()
                infoDict = {"href": href,
                            "class": "",
                            "displayName": escapeName(res.getDisplayName()),
                            "lastModified": res.getLastModified(),
                            "isCollection": res.isCollection,
                            "contentLength": res.getContentLength(),
                            "displayType": di.get("type"),
                            "displayTypeComment": di.get("typeComment"),
                            }

                if not isReadOnly and not res.isCollection:
                    ext = os.path.splitext(href)[1].lstrip(".").lower()
                    officeType = msOfficeExtToTypeMap.get(ext)
                    if officeType:
                        # print "OT", officeType
                        # print "OT", dirConfig
                        if dirConfig.get("ms_sharepoint_plugin"):
                            infoDict["class"] = "msoffice"
                        elif dirConfig.get("ms_sharepoint_urls"):
                            infoDict["href"] = "ms-%s:ofe|u|%s" % (officeType, href)

                dirInfoList.append(infoDict)
        # 
        for infoDict in dirInfoList:
            lastModified = infoDict.get("lastModified")
            if lastModified is None:
                infoDict["strModified"] = ""
            else:
                infoDict["strModified"] = util.getRfc1123Time(lastModified)
            
            infoDict["strSize"] = "-"
            if not infoDict.get("isCollection"):
                contentLength = infoDict.get("contentLength")
                if contentLength is not None:
                    infoDict["strSize"] = util.byteNumberString(contentLength)

            html.append("""\
            <tr><td><a href="%(href)s" class="%(class)s">%(displayName)s</a></td>
            <td>%(displayType)s</td>
            <td class='right'>%(strSize)s</td>
            <td class='right'>%(strModified)s</td></tr>""" % infoDict)
            
        html.append("</tbody>")
        html.append("</table>")

        html.append("<hr>") 

        if "http_authenticator.username" in environ:
            if environ.get("http_authenticator.username"):
                html.append("<p>Authenticated user: '******', realm: '%s'.</p>" 
                              % (environ.get("http_authenticator.username"),
                                 environ.get("http_authenticator.realm")))
#            else:
#                html.append("<p>Anonymous</p>")

        if trailer:
            html.append("<p class='trailer'>%s</p>" % trailer)

        html.append("</body></html>")

        body = "\n".join(html) 

        start_response("200 OK", [("Content-Type", "text/html"), 
                                  ("Content-Length", str(len(body))),
                                  ("Date", util.getRfc1123Time()),
                                  ])
        return [ body ] 
    def _listDirectory(self, davres, environ, start_response):
        """
        @see: http://www.webdav.org/specs/rfc4918.html#rfc.section.9.4
        """
        assert davres.isCollection

        dirConfig = environ["wsgidav.config"].get("dir_browser", {})
        displaypath = urllib.unquote(davres.getHref())

        trailer = dirConfig.get("response_trailer")
        if trailer:
            trailer = trailer.replace(
                "${version}",
                "<a href='http://wsgidav.googlecode.com/'>WsgiDAV/%s</a>" %
                __version__)
            trailer = trailer.replace("${time}", util.getRfc1123Time())
        else:
            trailer = (
                "<a href='http://wsgidav.googlecode.com/'>WsgiDAV/%s</a> - %s"
                % (__version__, util.getRfc1123Time()))

        html = []
        html.append(
            "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>"
        )
        html.append("<html>")
        html.append("<head>")
        html.append(
            "<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>"
        )
        html.append("<meta name='generator' content='WsgiDAV %s'>" %
                    __version__)
        html.append("<title>WsgiDAV - Index of %s </title>" % displaypath)

        html.append("""\
<style type="text/css">
    img { border: 0; padding: 0 2px; vertical-align: text-bottom; }
    th, td { padding: 2px 20px 2px 2px; }
    th { text-align: left; }
    th.right { text-align: right; }
    td  { font-family: monospace; vertical-align: bottom; white-space: pre; }
    td.right { text-align: right; }
    table { border: 0; }
    a.symlink { font-style: italic; }
    p.trailer { font-size: smaller; }
</style>""")
        # Special CSS to enable MS Internet Explorer behaviour
        if dirConfig.get("msmount"):
            html.append("""\
<style type="text/css">
    A {behavior: url(#default#AnchorClick);}
</style>""")

        html.append("</head><body>")

        # Title
        html.append("<h1>Index of %s</h1>" % displaypath)
        # Add DAV-Mount link and Web-Folder link
        links = []
        if dirConfig.get("davmount"):
            links.append(
                "<a title='Open this folder in a WebDAV client.' href='%s?davmount'>Mount</a>"
                % util.makeCompleteUrl(environ))
        if dirConfig.get("msmount"):
            links.append(
                "<a title='Open as Web Folder (requires Microsoft Internet Explorer)' href='' FOLDER='%s'>Open as Web Folder</a>"
                % util.makeCompleteUrl(environ))
#                html.append("<a href='' FOLDER='%ssetup.py'>Open setup.py as WebDAV</a>" % util.makeCompleteUrl(environ))
        if links:
            html.append("<p>%s</p>" % " &#8211; ".join(links))

        html.append("<hr>")
        # Listing
        html.append("<table>")

        html.append("<thead>")
        html.append(
            "<tr><th>Name</th> <th>Type</th> <th class='right'>Size</th> <th class='right'>Last modified</th> </tr>"
        )
        html.append("</thead>")

        html.append("<tbody>")
        if davres.path in ("", "/"):
            html.append(
                "<tr><td>Top level share</td> <td></td> <td></td> <td></td> </tr>"
            )
        else:
            parentUrl = util.getUriParent(davres.getHref())
            html.append(
                "<tr><td><a href='" + parentUrl +
                "'>Parent Directory</a></td> <td></td> <td></td> <td></td> </tr>"
            )

        # Ask collection for member info list
        dirInfoList = davres.getDirectoryInfo()

        if dirInfoList is None:
            # No pre-build info: traverse members
            dirInfoList = []
            childList = davres.getDescendants(depth="1", addSelf=False)
            for res in childList:
                di = res.getDisplayInfo()
                infoDict = {
                    "href": res.getHref(),
                    "displayName": res.getDisplayName(),
                    "lastModified": res.getLastModified(),
                    "isCollection": res.isCollection,
                    "contentLength": res.getContentLength(),
                    "displayType": di.get("type"),
                    "displayTypeComment": di.get("typeComment"),
                }
                dirInfoList.append(infoDict)
        #
        for infoDict in dirInfoList:
            lastModified = infoDict.get("lastModified")
            if lastModified is None:
                infoDict["strModified"] = ""
            else:
                infoDict["strModified"] = util.getRfc1123Time(lastModified)

            infoDict["strSize"] = "-"
            if not infoDict.get("isCollection"):
                contentLength = infoDict.get("contentLength")
                if contentLength is not None:
                    infoDict["strSize"] = util.byteNumberString(contentLength)

            html.append("""\
            <tr><td><a href="%(href)s">%(displayName)s</a></td>
            <td>%(displayType)s</td>
            <td class='right'>%(strSize)s</td>
            <td class='right'>%(strModified)s</td></tr>""" % infoDict)

        html.append("</tbody>")
        html.append("</table>")

        html.append("<hr>")

        if "http_authenticator.username" in environ:
            if environ.get("http_authenticator.username"):
                html.append("<p>Authenticated user: '******', realm: '%s'.</p>" %
                            (environ.get("http_authenticator.username"),
                             environ.get("http_authenticator.realm")))
#            else:
#                html.append("<p>Anonymous</p>")

        if trailer:
            html.append("<p class='trailer'>%s</p>" % trailer)
#            html.append("<p class='trailer'><a href='http://wsgidav.googlecode.com/'>WsgiDAV/%s</a> - %s</p>"
#                          % (__version__, util.getRfc1123Time()))

        html.append("</body></html>")

        body = "\n".join(html)

        start_response("200 OK", [
            ("Content-Type", "text/html"),
            ("Content-Length", str(len(body))),
            ("Date", util.getRfc1123Time()),
        ])
        return [body]
示例#14
0
                    util.warn("ErrorPrinter: caught Exception")
                    util.warn(traceback.format_exc())
                    raise
        except DAVError, e:
            _logger.debug("caught %s" % e)

            status = getHttpStatusString(e)
            # Dump internal errors to console
            if e.value == HTTP_INTERNAL_ERROR:
                util.warn(traceback.format_exc())
                util.warn("e.srcexception:\n%s" % e.srcexception)
            elif e.value in (HTTP_NOT_MODIFIED, HTTP_NO_CONTENT):
#                util.log("ErrorPrinter: forcing empty error response for %s" % e.value)
                # See paste.lint: these code don't have content
                start_response(status, [("Content-Length", "0"),
                                        ("Date", util.getRfc1123Time()),
                                        ])
                yield ""
                return

            # If exception has pre-/post-condition: return as XML response, 
            # else return as HTML 
            content_type, body = e.getResponsePage()            

            # TODO: provide exc_info=sys.exc_info()?
            start_response(status, [("Content-Type", content_type), 
                                    ("Content-Length", str(len(body))),
                                    ("Date", util.getRfc1123Time()),
                                    ])
            yield body 
            return
示例#15
0
    def _listDirectory(self, davres, environ, start_response):
        """
        @see: http://www.webdav.org/specs/rfc4918.html#rfc.section.9.4
        """
        assert davres.isCollection
        
        dirConfig = environ["wsgidav.config"].get("dir_browser", {})
        displaypath = urllib.unquote(davres.getHref())
        isReadOnly = environ["wsgidav.provider"].isReadOnly()

        trailer = dirConfig.get("response_trailer")
        if trailer:
            trailer = trailer.replace("${version}", 
                "<a href='https://github.com/mar10/wsgidav/'>WsgiDAV/%s</a>" % __version__)
            trailer = trailer.replace("${time}", util.getRfc1123Time())
        else:
            trailer = ("<a href='https://github.com/mar10/wsgidav/'>WsgiDAV/%s</a> - %s" 
                       % (__version__, util.getRfc1123Time()))

        
        html = []
        html.append("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>");
        html.append("<html>")
        html.append("<head>")
        html.append("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>")
        html.append("<meta name='generator' content='WsgiDAV %s'>" % __version__)
        html.append("<title>WsgiDAV - Index of %s </title>" % displaypath)
        
        html.append("<script type='text/javascript'>%s</script>" % PAGE_SCRIPT)
        html.append("<style type='text/css'>%s</style>" % PAGE_CSS)

        # Special CSS to enable MS Internet Explorer behaviour
        if dirConfig.get("ms_mount"):
            html.append("<style type='text/css'> A {behavior: url(#default#AnchorClick);} </style>")
        
        if dirConfig.get("ms_sharepoint_plugin"):
            html.append("<object id='winFirefoxPlugin' type='application/x-sharepoint' width='0' height='0' style=''visibility: hidden;'></object>")

        html.append("</head>")
        html.append("<body onload='onLoad()'>")

        # Title
        html.append("<h1>Index of %s</h1>" % displaypath)
        # Add DAV-Mount link and Web-Folder link
        links = []
        if dirConfig.get("davmount"):
            links.append("<a title='Open this folder in a WebDAV client.' href='%s?davmount'>Mount</a>" % util.makeCompleteUrl(environ))
        if dirConfig.get("ms_mount"):
            links.append("<a title='Open as Web Folder (requires Microsoft Internet Explorer)' href='' FOLDER='%s'>Open as Web Folder</a>" % util.makeCompleteUrl(environ))
#                html.append("<a href='' FOLDER='%ssetup.py'>Open setup.py as WebDAV</a>" % util.makeCompleteUrl(environ))
        if links:
            html.append("<p>%s</p>" % " &#8211; ".join(links))

        html.append("<hr>")
        # Listing
        html.append("<table onclick='return onClickTable(event)'>")

        html.append("<thead>")
        html.append("<tr><th>Name</th> <th>Type</th> <th class='right'>Size</th> <th class='right'>Last modified</th> </tr>")
        html.append("</thead>")
            
        html.append("<tbody>")
        if davres.path in ("", "/"):
            html.append("<tr><td>Top level share</td> <td></td> <td></td> <td></td> </tr>")
        else:
            parentUrl = util.getUriParent(davres.getHref())
            html.append("<tr><td><a href='" + parentUrl + "'>Parent Directory</a></td> <td></td> <td></td> <td></td> </tr>")

        # Ask collection for member info list
        dirInfoList = davres.getDirectoryInfo()

        if dirInfoList is None:
            # No pre-build info: traverse members
            dirInfoList = []
            childList = davres.getDescendants(depth="1", addSelf=False)
            for res in childList:
                di = res.getDisplayInfo()
                href = res.getHref()
                infoDict = {"href": href,
                            "class": "",
                            "displayName": res.getDisplayName(),
                            "lastModified": res.getLastModified(),
                            "isCollection": res.isCollection,
                            "contentLength": res.getContentLength(),
                            "displayType": di.get("type"),
                            "displayTypeComment": di.get("typeComment"),
                            }

                if not isReadOnly and not res.isCollection:
                    ext = os.path.splitext(href)[1].lstrip(".").lower()
                    officeType = msOfficeExtToTypeMap.get(ext)
                    if officeType:
                        print "OT", officeType
                        print "OT", dirConfig
                        if dirConfig.get("ms_sharepoint_plugin"):
                            infoDict["class"] = "msoffice"
                        elif dirConfig.get("ms_sharepoint_urls"):
                            infoDict["href"] = "ms-%s:ofe|u|%s" % (officeType, href)

                dirInfoList.append(infoDict)
        # 
        for infoDict in dirInfoList:
            lastModified = infoDict.get("lastModified")
            if lastModified is None:
                infoDict["strModified"] = ""
            else:
                infoDict["strModified"] = util.getRfc1123Time(lastModified)
            
            infoDict["strSize"] = "-"
            if not infoDict.get("isCollection"):
                contentLength = infoDict.get("contentLength")
                if contentLength is not None:
                    infoDict["strSize"] = util.byteNumberString(contentLength)

            html.append("""\
            <tr><td><a href="%(href)s" class="%(class)s">%(displayName)s</a></td>
            <td>%(displayType)s</td>
            <td class='right'>%(strSize)s</td>
            <td class='right'>%(strModified)s</td></tr>""" % infoDict)
            
        html.append("</tbody>")
        html.append("</table>")

        html.append("<hr>") 

        if "http_authenticator.username" in environ:
            if environ.get("http_authenticator.username"):
                html.append("<p>Authenticated user: '******', realm: '%s'.</p>" 
                              % (environ.get("http_authenticator.username"),
                                 environ.get("http_authenticator.realm")))
#            else:
#                html.append("<p>Anonymous</p>")

        if trailer:
            html.append("<p class='trailer'>%s</p>" % trailer)

        html.append("</body></html>")

        body = "\n".join(html) 

        start_response("200 OK", [("Content-Type", "text/html"), 
                                  ("Content-Length", str(len(body))),
                                  ("Date", util.getRfc1123Time()),
                                  ])
        return [ body ] 
示例#16
0
        except DAVError, e:
            _logger.debug("caught %s" % e)

            status = getHttpStatusString(e)
            # Dump internal errors to console
            if e.value == HTTP_INTERNAL_ERROR:
                print >> sys.stdout, "ErrorPrinter: caught HTTPRequestException(HTTP_INTERNAL_ERROR)"
                traceback.print_exc(10,
                                    environ.get("wsgi.errors") or sys.stdout)
                print >> sys.stdout, "e.srcexception:\n%s" % e.srcexception
            elif e.value in (HTTP_NOT_MODIFIED, HTTP_NO_CONTENT):
                #                util.log("ErrorPrinter: forcing empty error response for %s" % e.value)
                # See paste.lint: these code don't have content
                start_response(status, [
                    ("Content-Length", "0"),
                    ("Date", util.getRfc1123Time()),
                ])
                yield ""
                return

            # If exception has pre-/post-condition: return as XML response,
            # else return as HTML
            content_type, body = e.getResponsePage()

            # TODO: provide exc_info=sys.exc_info()?
            start_response(status, [
                ("Content-Type", content_type),
                ("Content-Length", str(len(body))),
                ("Date", util.getRfc1123Time()),
            ])
            yield body
示例#17
0
    def _listDirectory(self, davres, environ, start_response):
        """
        @see: http://www.webdav.org/specs/rfc4918.html#rfc.section.9.4
        """
        assert davres.isCollection
        
        dirConfig = environ["wsgidav.config"].get("dir_browser", {})
        displaypath = urllib.unquote(davres.getHref())

        trailer = dirConfig.get("response_trailer")
        if trailer:
            trailer = trailer.replace("${version}", 
                "<a href='http://wsgidav.googlecode.com/'>WsgiDAV/%s</a>" % __version__)
            trailer = trailer.replace("${time}", util.getRfc1123Time())
        else:
            trailer = ("<a href='http://wsgidav.googlecode.com/'>WsgiDAV/%s</a> - %s" 
                       % (__version__, util.getRfc1123Time()))

        
        html = []
        html.append("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>");
        html.append("<html>")
        html.append("<head>")
        html.append("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>")
        html.append("<meta name='generator' content='WsgiDAV %s'>" % __version__)
        html.append("<title>WsgiDAV - Index of %s </title>" % displaypath)
        
        html.append("""\
<style type="text/css">
    img { border: 0; padding: 0 2px; vertical-align: text-bottom; }
    th, td { padding: 2px 20px 2px 2px; }
    th { text-align: left; }
    th.right { text-align: right; }
    td  { font-family: monospace; vertical-align: bottom; white-space: pre; }
    td.right { text-align: right; }
    table { border: 0; }
    a.symlink { font-style: italic; }
    p.trailer { font-size: smaller; }
</style>""")        
        # Special CSS to enable MS Internet Explorer behaviour
        if dirConfig.get("msmount"):
            html.append("""\
<style type="text/css">
    A {behavior: url(#default#AnchorClick);}
</style>""")
        
        html.append("</head><body>")

        # Title
        html.append("<h1>Index of %s</h1>" % displaypath)
        # Add DAV-Mount link and Web-Folder link
        links = []
        if dirConfig.get("davmount"):
            links.append("<a title='Open this folder in a WebDAV client.' href='%s?davmount'>Mount</a>" % util.makeCompleteUrl(environ))
        if dirConfig.get("msmount"):
            links.append("<a title='Open as Web Folder (requires Microsoft Internet Explorer)' href='' FOLDER='%s'>Open as Web Folder</a>" % util.makeCompleteUrl(environ))
#                html.append("<a href='' FOLDER='%ssetup.py'>Open setup.py as WebDAV</a>" % util.makeCompleteUrl(environ))
        if links:
            html.append("<p>%s</p>" % " &#8211; ".join(links))

        html.append("<hr>")
        # Listing
        html.append("<table>")

        html.append("<thead>")
        html.append("<tr><th>Name</th> <th>Type</th> <th class='right'>Size</th> <th class='right'>Last modified</th> </tr>")
        html.append("</thead>")
            
        html.append("<tbody>")
        if davres.path in ("", "/"):
            html.append("<tr><td>Top level share</td> <td></td> <td></td> <td></td> </tr>")
        else:
            parentUrl = util.getUriParent(davres.getHref())
            html.append("<tr><td><a href='" + parentUrl + "'>Parent Directory</a></td> <td></td> <td></td> <td></td> </tr>")

        # Ask collection for member info list
        dirInfoList = davres.getDirectoryInfo()

        if dirInfoList is None:
            # No pre-build info: traverse members
            dirInfoList = []
            childList = davres.getDescendants(depth="1", addSelf=False)
            for res in childList:
                di = res.getDisplayInfo()
                infoDict = {"href": res.getHref(),
                            "displayName": res.getDisplayName(),
                            "lastModified": res.getLastModified(),
                            "isCollection": res.isCollection,
                            "contentLength": res.getContentLength(),
                            "displayType": di.get("type"),
                            "displayTypeComment": di.get("typeComment"),
                            }
                dirInfoList.append(infoDict)
        # 
        for infoDict in dirInfoList:
            lastModified = infoDict.get("lastModified")
            if lastModified is None:
                infoDict["strModified"] = ""
            else:
                infoDict["strModified"] = util.getRfc1123Time(lastModified)
            
            infoDict["strSize"] = "-"
            if not infoDict.get("isCollection"):
                contentLength = infoDict.get("contentLength")
                if contentLength is not None:
                    infoDict["strSize"] = util.byteNumberString(contentLength)

            html.append("""\
            <tr><td><a href="%(href)s">%(displayName)s</a></td>
            <td>%(displayType)s</td>
            <td class='right'>%(strSize)s</td>
            <td class='right'>%(strModified)s</td></tr>""" % infoDict)
            
        html.append("</tbody>")
        html.append("</table>")

        html.append("<hr>") 

        if "http_authenticator.username" in environ:
            if environ.get("http_authenticator.username"):
                html.append("<p>Authenticated user: '******', realm: '%s'.</p>" 
                              % (environ.get("http_authenticator.username"),
                                 environ.get("http_authenticator.realm")))
#            else:
#                html.append("<p>Anonymous</p>")

        if trailer:
            html.append("<p class='trailer'>%s</p>" % trailer)
#            html.append("<p class='trailer'><a href='http://wsgidav.googlecode.com/'>WsgiDAV/%s</a> - %s</p>" 
#                          % (__version__, util.getRfc1123Time()))

        html.append("</body></html>")

        body = "\n".join(html) 

        start_response("200 OK", [("Content-Type", "text/html"), 
                                  ("Content-Length", str(len(body))),
                                  ("Date", util.getRfc1123Time()),
                                  ])
        return [ body ]