コード例 #1
0
    def do_PUT(self):
        dc = self.IFACE_CLASS
        uri = urlparse.urljoin(self.get_baseuri(dc), self.path)
        uri = urllib.unquote(uri)

        log.debug("do_PUT: uri = %s" % uri)
        log.debug('do_PUT: headers = %s' % self.headers)
        # Handle If-Match
        if self.headers.has_key('If-Match'):
            log.debug("do_PUT: If-Match %s" % self.headers['If-Match'])
            test = False
            etag = None
            try:
                etag = dc.get_prop(uri, "DAV:", "getetag")
            except:
                pass

            log.debug("do_PUT: etag = %s" % etag)

            for match in self.headers['If-Match'].split(','):
                if match == '*':
                    if dc.exists(uri):
                        test = True
                        break
                else:
                    if match == etag:
                        test = True
                        break
            if not test:
                self.send_status(412)
                self.log_request(412)
                return

        # Handle If-None-Match
        if self.headers.has_key('If-None-Match'):
            log.debug("do_PUT: If-None-Match %s" %
                      self.headers['If-None-Match'])

            test = True
            etag = None
            try:
                etag = dc.get_prop(uri, "DAV:", "getetag")
            except:
                pass

            log.debug("do_PUT: etag = %s" % etag)

            for match in self.headers['If-None-Match'].split(','):
                if match == '*':
                    if dc.exists(uri):
                        test = False
                        break
                else:
                    if match == etag:
                        test = False
                        break
            if not test:
                self.send_status(412)
                self.log_request(412)
                return

        # locked resources are not allowed to be overwritten
        ifheader = self.headers.get('If')
        if ((self._l_isLocked(uri)) and (not ifheader)):
            return self.send_body(None, '423', 'Locked', 'Locked')

        if ((self._l_isLocked(uri)) and (ifheader)):
            uri_token = self._l_getLockForUri(uri)
            taglist = IfParser(ifheader)
            found = False
            for tag in taglist:
                for listitem in tag.list:
                    token = tokenFinder(listitem)
                    if (token and (self._l_hasLock(token))
                            and (self._l_getLock(token) == uri_token)):
                        found = True
                        break
                if found:
                    break
            if not found:
                res = self.send_body(None, '423', 'Locked', 'Locked')
                self.log_request(423)
                return res

        # Handle expect
        expect = self.headers.get('Expect', '')
        if (expect.lower() == '100-continue'
                and self.protocol_version >= 'HTTP/1.1'
                and self.request_version >= 'HTTP/1.1'):
            self.send_status(100)
            self._flush()

        content_type = None
        if self.headers.has_key("Content-Type"):
            content_type = self.headers['Content-Type']

        headers = {}
        headers['Location'] = uri

        try:
            etag = dc.get_prop(uri, "DAV:", "getetag")
            headers['ETag'] = etag
        except:
            pass

        expect = self.headers.get('transfer-encoding', '')
        if (expect.lower() == 'chunked' and self.protocol_version >= 'HTTP/1.1'
                and self.request_version >= 'HTTP/1.1'):
            self.send_body(None, '201', 'Created', '', headers=headers)
            self._flush()

            dc.put(uri, self._readChunkedData(), content_type)
        else:
            # read the body
            body = None
            if self.headers.has_key("Content-Length"):
                l = self.headers['Content-Length']
                log.debug("do_PUT: Content-Length = %s" % l)
                body = self._readNoChunkedData(atoi(l))
            else:
                log.debug("do_PUT: Content-Length = empty")

            try:
                dc.put(uri, body, content_type)
            except DAV_Error, (ec, dd):
                return self.send_status(ec)

            self.send_body(None, '201', 'Created', '', headers=headers)
            self.log_request(201)
コード例 #2
0
ファイル: WebDAVServer.py プロジェクト: cernbox/pywebdav
    def do_PUT(self):
        dc = self.IFACE_CLASS
        uri = urlparse.urljoin(self.get_baseuri(dc), self.path)
        uri = urllib.unquote(uri)

        log.debug("do_PUT: uri = %s" % uri)
        log.debug('do_PUT: headers = %s' % self.headers)
        # Handle If-Match
        if 'If-Match' in self.headers:
            log.debug("do_PUT: If-Match %s" % self.headers['If-Match'])
            test = False
            etag = None
            try:
                etag = dc.get_prop(uri, "DAV:", "getetag")
            except:
                pass

            log.debug("do_PUT: etag = %s" % etag)

            for match in self.headers['If-Match'].split(','):
                if match == '*':
                    if dc.exists(uri):
                        test = True
                        break
                else:
                    if match == etag:
                        test = True
                        break
            if not test:
                self.send_status(412)
                self.log_request(412)
                return

        # Handle If-None-Match
        if 'If-None-Match' in self.headers:
            log.debug("do_PUT: If-None-Match %s" %
                      self.headers['If-None-Match'])

            test = True
            etag = None
            try:
                etag = dc.get_prop(uri, "DAV:", "getetag")
            except:
                pass

            log.debug("do_PUT: etag = %s" % etag)

            for match in self.headers['If-None-Match'].split(','):
                if match == '*':
                    if dc.exists(uri):
                        test = False
                        break
                else:
                    if match == etag:
                        test = False
                        break
            if not test:
                self.send_status(412)
                self.log_request(412)
                return

        # locked resources are not allowed to be overwritten
        ifheader = self.headers.get('If')
        if ((self._l_isLocked(uri)) and (not ifheader)):
            return self.send_body(None, 423, 'Locked', 'Locked')

        if ((self._l_isLocked(uri)) and (ifheader)):
            uri_token = self._l_getLockForUri(uri)
            taglist = IfParser(ifheader)
            found = False
            for tag in taglist:
                for listitem in tag.list:
                    token = tokenFinder(listitem)
                    if (token and (self._l_hasLock(token))
                            and (self._l_getLock(token) == uri_token)):
                        found = True
                        break
                if found:
                    break
            if not found:
                res = self.send_body(None, 423, 'Locked', 'Locked')
                self.log_request(423)
                return res

        # Handle expect
        expect = self.headers.get('Expect', '')
        if (expect.lower() == '100-continue'
                and self.protocol_version >= 'HTTP/1.1'
                and self.request_version >= 'HTTP/1.1'):
            self.send_status(100)

        content_type = None
        if 'Content-Type' in self.headers:
            content_type = self.headers['Content-Type']

        headers = {}
        headers['Location'] = uri

        try:
            etag = dc.get_prop(uri, "DAV:", "getetag")
            headers['ETag'] = etag
        except:
            pass

        expect = self.headers.get('transfer-encoding', '')
        if (expect.lower() == 'chunked' and self.protocol_version >= 'HTTP/1.1'
                and self.request_version >= 'HTTP/1.1'):
            self.send_body(None, 201, 'Created', '', headers=headers)

            dc.put(uri, self._readChunkedData(), content_type)
        else:
            # read the body
            body = None
            if 'Content-Length' in self.headers:
                l = self.headers['Content-Length']
                log.debug("do_PUT: Content-Length = %s" % l)
                body = self._readNoChunkedData(atoi(l))
            else:
                log.debug("do_PUT: Content-Length = empty")

            try:
                dc.put(uri, body, content_type)
            except DAV_Error, (ec, dd):
                return self.send_status(ec)

            # get the ETAG of the already existing file on the server
            try:
                etag = dc.get_prop(uri, "DAV:", "getetag")
                headers['ETag'] = etag
            except:
                pass

            if self.headers.has_key('X-OC-Mtime'):
                import os
                mtime = int(self.headers['X-OC-Mtime'])
                fn = dc.uri2local(uri)
                atime = os.stat(fn).st_atime
                print 'setting utime:', fn, (atime, mtime)
                os.utime(fn, (atime, mtime))

                dn = os.path.dirname(fn)
                while dn != dc.directory:
                    print 'setting directory utime:', dn
                    os.utime(dn, None)
                    dn = os.path.dirname(dn)

                headers['X-OC-Mtime'] = 'accepted'

            headers['OC-FileId'] = dc.get_prop(uri, 'http://owncloud.org/ns',
                                               'id')

            self.send_body(None, 201, 'Created', '', headers=headers)
            self.log_request(201)
コード例 #3
0
    def do_LOCK(self):
        """ Locking is implemented via in-memory caches. No data is written to disk.  """

        dc = self.IFACE_CLASS

        log.info('LOCKing resource %s' % self.headers)

        body = None
        if self.headers.has_key('Content-Length'):
            l = self.headers['Content-Length']
            body = self.rfile.read(atoi(l))

        depth = self.headers.get('Depth', 'infinity')

        uri = urlparse.urljoin(self.get_baseuri(dc), self.path)
        uri = urllib.unquote(uri)
        log.info('do_LOCK: uri = %s' % uri)

        ifheader = self.headers.get('If')
        alreadylocked = self._l_isLocked(uri)
        log.info('do_LOCK: alreadylocked = %s' % alreadylocked)

        if body and alreadylocked:
            # Full LOCK request but resource already locked
            self.responses[423] = ('Locked', 'Already locked')
            return self.send_status(423)

        elif body and not ifheader:
            # LOCK with XML information
            data = self._lock_unlock_parse(body)
            token, result = self._lock_unlock_create(uri, 'unknown', depth,
                                                     data)

            if result:
                self.send_body(result, '207', 'Error', 'Error',
                               'text/xml; charset="utf-8"')

            else:
                lock = self._l_getLock(token)
                self.send_body(lock.asXML(), '200', 'OK', 'OK',
                               'text/xml; charset="utf-8"',
                               {'Lock-Token': '<opaquelocktoken:%s>' % token})

        else:
            # refresh request - refresh lock timeout
            taglist = IfParser(ifheader)
            found = 0
            for tag in taglist:
                for listitem in tag.list:
                    token = tokenFinder(listitem)
                    if token and self._l_hasLock(token):
                        lock = self._l_getLock(token)
                        timeout = self.headers.get('Timeout', 'Infinite')
                        lock.setTimeout(timeout)  # automatically refreshes
                        found = 1

                        self.send_body(lock.asXML(), '200', 'OK', 'OK',
                                       'text/xml; encoding="utf-8"')
                        break
                if found:
                    break

            # we didn't find any of the tokens mentioned - means
            # that table was cleared or another error
            if not found:
                self.send_status(412)  # precondition failed