Example #1
0
    def _check_resource_attribute(self, env, start_response):
        """
        This method checks if a given url points to either a container, or
        an object or does not exist. It will also check if a resource is a
        virtual container in CDMI term. If a resource exists, the headers
        will also be return in following sequence.
        res - The response which containers errors, None means there is no
        error
        is_container - if it is a container, it is True, otherwise, it is
        False
        headers - if the resource exists, this holds the headers
        children - if it is a container, return container's child list
        """
        path = env["PATH_INFO"]
        res, is_container, headers, children = None, False, {}, None
        exists, headers, dummy = check_resource(env, "GET", path, self.logger)
        # If exists, we need to check if the resource is a container
        if exists:
            content_type = (headers.get("content-type") or "").lower()
            if content_type.find("application/directory") < 0 and self.object_name:
                is_container = False
            else:
                is_container = True
        # None self.object_name means that we are dealing with a real OS
        # container, return resource not found error
        elif not self.object_name:
            res = get_err_response("NoSuchKey")

        if res is None and (not exists or is_container):
            # Now we will try to get the children of the container and also
            # do more checks to see if there is any virtual resources.
            path = "/" + concat_parts("v1", self.account_name, self.container_name)
            query_string = "delimiter=/"
            if self.object_name:
                query_string += "&prefix=" + concat_parts(self.parent_name, self.object_name) + "/"

            container_exists, dummy, body = check_resource(env, "GET", path, self.logger, True, query_string)
            if container_exists:
                try:
                    children = json.loads(body)
                    no_of_children = len(children)
                    # The entity could be a virtual container since it
                    # does not exist
                    if not exists:
                        # There is no children under also not exists,
                        # it is not virtual container.
                        if no_of_children <= 0:
                            res = get_err_response("NoSuchKey")
                        # There are children under and not exist, it is
                        # a virtual container
                        elif no_of_children > 0 and not exists:
                            is_container = True
                except ValueError:
                    res = get_err_response("InconsistantState")
            else:
                res = get_err_response("NoSuchKey")

        return res, is_container, headers, children
Example #2
0
    def DELETE(self, env, start_response):
        """
        Handle DELETE both container and data object removal.
        """

        path = "/v1/" + self.account_name + "/" + self.container_name
        query_string = "delimiter=/"
        if self.object_name:
            query_string += "&prefix=" + concat_parts(self.parent_name, self.object_name) + "/"
        exists, dummy, body = check_resource(env, "GET", path, self.logger, True, query_string)
        # Not even the top container exist, so there is no such resource.
        if not exists:
            return get_err_response("NoSuchKey")
        # Top container exists, check if there is anything under.
        else:
            try:
                children = json.loads(body)
                # there are some children under
                if len(children) > 0:
                    return get_err_response("ContainerNotEmpty")
            except ValueError:
                return get_err_response("InconsistantState")

        # Create a new WebOb Request object according to the current request
        req = Request(env)
        # Now send the request over.
        return req.get_response(self.app)
    def PUT(self, env, start_response):
        """ Handle Container update and create request """

        # First check if the resource exists and if it is a directory
        path = '/' + concat_parts('v1', self.account_name, self.container_name,
                                  self.parent_name, self.object_name)

        exists, headers, body = check_resource(env, 'GET', path,
                                               self.logger, False)

        if exists:
            content_type = headers.get('content-type', '')
            content_type = content_type.lower() if content_type else ''
            if (content_type.find('application/directory') < 0 and
                self.object_name):
                return get_err_response('Conflict')
        else:
            res = self._check_parent(env, start_response)
            if res:
                return res

        req = Request(env)
        req.headers['content-type'] = 'application/directory'
        req.headers['content-length'] = '0'
        req.body = ''
        res = req.get_response(self.app)
        return res
Example #4
0
    def DELETE(self, env, start_response):
        """
        Handle DELETE both container and data object removal.
        """

        path = '/v1/' + self.account_name + '/' + self.container_name
        query_string = 'delimiter=/'
        if self.object_name:
            query_string += '&prefix=' + concat_parts(self.parent_name,
                                                      self.object_name) + '/'
        exists, dummy, body = check_resource(env, 'GET', path, self.logger,
                                             True, query_string)
        # Not even the top container exist, so there is no such resource.
        if not exists:
            return get_err_response('NoSuchKey')
        # Top container exists, check if there is anything under.
        else:
            try:
                children = json.loads(body)
                #there are some children under
                if len(children) > 0:
                    return get_err_response('ContainerNotEmpty')
            except ValueError:
                return get_err_response('InconsistantState')

        # Create a new WebOb Request object according to the current request
        req = Request(env)
        # Now send the request over.
        return req.get_response(self.app)
    def PUT(self, env, start_response):
        """ Handle Container update and create request """

        # First check if the resource exists and if it is a directory
        path = '/' + concat_parts('v1', self.account_name, self.container_name,
                                  self.parent_name, self.object_name)

        exists, headers, body = check_resource(env, 'GET', path, self.logger,
                                               False)

        if exists:
            content_type = headers.get('content-type', '')
            content_type = content_type.lower() if content_type else ''
            if (content_type.find('application/directory') < 0
                    and self.object_name):
                return get_err_response('Conflict')
        else:
            res = self._check_parent(env, start_response)
            if res:
                return res

        req = Request(env)
        req.headers['content-type'] = 'application/directory'
        req.headers['content-length'] = '0'
        req.body = ''
        res = req.get_response(self.app)
        return res
Example #6
0
    def _check_parent(self, env, start_response):
        """
        This method checks if the parent really represents a directory.
        Returns error if parent does not exist or the parent actually points
        to a non directory. Returns None means that the parent points to a
        valid container (top container or virtual container)
        """
        if self.parent_name:
            # Try to hit the resource url and see if it exists
            path = '/' + concat_parts('v1', self.account_name,
                                      self.container_name, self.parent_name)
            exists, headers, dummy = check_resource(env, 'GET',
                                                    path, self.logger)
            if exists:
                content_type = str(headers.get('content-type', ''))
                if content_type.find('application/directory') < 0:
                    return get_err_response('InvalidContainerName')
                else:
                    return None
            else:
                # Check if there is anything below that parent, if it is,
                # then this is actually a virtual container.
                path = '/' + concat_parts('v1', self.account_name,
                                          self.container_name)
                query_string = 'delimiter=/&prefix=' + self.parent_name + '/'
                parent_exists, dummy, body = check_resource(env, 'GET', path,
                                                            self.logger, True,
                                                            query_string)
                if parent_exists:
                    try:
                        children = json.loads(body)
                        if len(children) <= 0:
                            # No children under, no resource exist
                            return get_err_response('NoParentContainer')
                        else:
                            return None
                    except ValueError:
                        return get_err_response('InconsistantState')
                # The root container does not event exist, this is an error
                else:
                    return get_err_response('NoParentContainer')

        return None
Example #7
0
    def _check_parent(self, env, start_response):
        """
        This method checks if the parent really represents a directory.
        Returns error if parent does not exist or the parent actually points
        to a non directory. Returns None means that the parent points to a
        valid container (top container or virtual container)
        """
        if self.parent_name:
            # Try to hit the resource url and see if it exists
            path = '/' + concat_parts('v1', self.account_name,
                                      self.container_name, self.parent_name)
            exists, headers, dummy = check_resource(env, 'GET',
                                                    path, self.logger)
            if exists:
                content_type = str(headers.get('content-type', ''))
                if content_type.find('application/directory') < 0:
                    return get_err_response('InvalidContainerName')
                else:
                    return None
            else:
                # Check if there is anything below that parent, if it is,
                # then this is actually a virtual container.
                path = '/' + concat_parts('v1', self.account_name,
                                          self.container_name)
                query_string = 'delimiter=/&prefix=' + self.parent_name + '/'
                parent_exists, dummy, body = check_resource(env, 'GET', path,
                                                            self.logger, True,
                                                            query_string)
                if parent_exists:
                    try:
                        children = json.loads(body)
                        if len(children) <= 0:
                            # No children under, no resource exist
                            return get_err_response('NoParentContainer')
                        else:
                            return None
                    except ValueError:
                        return get_err_response('InconsistantState')
                # The root container does not event exist, this is an error
                else:
                    return get_err_response('NoParentContainer')

        return None
Example #8
0
    def _check_resource_attribute(self, env, start_response):
        """
        This method checks if a given url points to either a container, or
        an object or does not exist. It will also check if a resource is a
        virtual container in CDMI term. If a resource exists, the headers
        will also be return in following sequence.
        res - The response which containers errors, None means there is no
        error
        is_container - if it is a container, it is True, otherwise, it is
        False
        headers - if the resource exists, this holds the headers
        children - if it is a container, return container's child list
        """
        path = env['PATH_INFO']
        res, is_container, headers, children = None, False, {}, None
        exists, headers, dummy = check_resource(env, 'GET', path, self.logger)
        # If exists, we need to check if the resource is a container
        if exists:
            content_type = (headers.get('content-type') or '').lower()
            if (content_type.find('application/directory') < 0 and
                self.object_name):
                is_container = False
            else:
                is_container = True
        # None self.object_name means that we are dealing with a real OS
        # container, return resource not found error
        elif not self.object_name:
            res = get_err_response('NoSuchKey')

        if res is None and (not exists or is_container):
            # Now we will try to get the children of the container and also
            # do more checks to see if there is any virtual resources.
            path = '/' + concat_parts('v1', self.account_name,
                                      self.container_name)
            query_string = 'delimiter=/'
            if self.object_name:
                query_string += ('&prefix=' +
                                 concat_parts(self.parent_name,
                                              self.object_name) +
                                 '/')

            container_exists, dummy, body = check_resource(env, 'GET', path,
                                                           self.logger, True,
                                                           query_string)
            if container_exists:
                try:
                    children = json.loads(body)
                    no_of_children = len(children)
                    # The entity could be a virtual container since it
                    # does not exist
                    if not exists:
                        # There is no children under also not exists,
                        # it is not virtual container.
                        if no_of_children <= 0:
                            res = get_err_response('NoSuchKey')
                        # There are children under and not exist, it is
                        # a virtual container
                        elif no_of_children > 0 and not exists:
                            is_container = True
                except ValueError:
                    res = get_err_response('InconsistantState')
            else:
                res = get_err_response('NoSuchKey')

        return res, is_container, headers, children
Example #9
0
    def PUT(self, env, start_response):
        """
        Handle Container update and create request
        """

        # First check if the resource exists and if it is a directory
        path = '/' + concat_parts('v1', self.account_name, self.container_name,
                                  self.parent_name, self.object_name)
        exists, headers, dummy = check_resource(env, 'GET', path,
                                                self.logger, False)
        if exists:
            content_type = headers.get('content-type', '')
            content_type = content_type.lower() if content_type else ''
            if (content_type.find('application/directory') < 0 and
                self.object_name):
                return get_err_response('Conflict')
        # Not a top container, so it has to be virtual container
        else:
            res = self._check_parent(env, start_response)
            if res:
                return res

        # Create a new WebOb Request object according to the current request
        req = Request(env)

        # We are creating a container, set the content-type to be
        # application/directory
        req.headers['content-type'] = 'application/directory'

        metadata = {}
        if req.body:
            try:
                body = json.loads(req.body)
            except ValueError:
                return get_err_response('InvalidContent')

            metadata = body.get('metadata')
            if metadata:
                for key in metadata:
                    if metadata[key] == '':
                        req.headers[self.metadata_prefix + key] = ''
                    else:
                        req.headers[self.metadata_prefix + key] = \
                            key + ":" + str(metadata[key])
            else:
                metadata = {}

        # Now set the body to be empty and content-length to 0
        req.body = ''
        req.headers['Content-Length'] = 0

        res = req.get_response(self.app)

        # Deal with the response now.
        # Build the response message body according to CDMI specification
        # if the response status is 201, then we know we have successfully
        # created the container. According to CDMI spec, only send response
        # body when creating new container
        if res.status_int == 201:
            body = {}
            body['objectType'] = Consts.CDMI_APP_CONTAINER
            body['objectName'] = (self.object_name + '/') if self.object_name \
                else (self.container_name + '/')
            if self.object_name:
                body['parentURI'] = '/'.join(['', self.cdmi_root,
                                              self.account_name,
                                              self.container_name,
                                              self.parent_name, ''])
            else:
                body['parentURI'] = '/'.join(['', self.cdmi_root,
                                              self.account_name, ''])

            body['capabilitiesURI'] = '/'.join(['', self.cdmi_root,
                                                self.account_name,
                                                self.cdmi_capability_id,
                                                'container/'])
            body['completionStatus'] = 'Complete'
            body['metadata'] = metadata
            res.body = json.dumps(body, indent=2)
        # Otherwise, no body should be returned.
        else:
            res.body = ''

        return res
Example #10
0
    def PUT(self, env, start_response):
        """
        Handle Container update and create request
        """
        # First check if the resource exists and if it is a directory
        path = '/' + concat_parts('v1', self.account_name, self.container_name,
                                  self.parent_name, self.object_name)
        exists, headers, body = check_resource(env, 'GET', path, self.logger,
                                               False, None)
        if exists:
            content_type = headers.get('content-type', '')
            content_type = content_type.lower() if content_type else ''
            if content_type.find('application/directory') >= 0:
                return get_err_response('Conflict')
        else:
            path = '/' + concat_parts('v1', self.account_name,
                                      self.container_name)
            query_string = 'delimiter=/&prefix=' + \
                concat_parts(self.parent_name, self.object_name) + '/'
            parent_exists, dummy, body = check_resource(env, 'GET', path,
                                                        self.logger, True,
                                                        query_string)
            if parent_exists:
                try:
                    children = json.loads(body)
                    if len(children) > 0:
                        # No children under, no resource exist
                        return get_err_response('Conflict')
                except ValueError:
                    return get_err_response('InconsistantState')
            else:
                return get_err_response('NoParentContainer')

        # Check if the parent is OK. it should be either a real directory or
        # a virtual directory
        res = self._check_parent(env, start_response)
        if res:
            return res

        # Create a new WebOb Request object according to the current request
        #if we found X-Object-UploadID in the header, we need know that
        #the request is uploading a piece of a large object, the piece
        #will need to go to the segments folder

        try:
            self._handle_part(env)
        except Exception as ex:
            return get_err_response(ex.message)

        req = Request(env)

        metadata = {}
        if req.body:
            try:
                body = self._handle_body(env, True)
            except Exception:
                return get_err_response('InvalidBody')

            # headling copy object
            if body.get('copy'):
                # add the copy-from header to indicate a copy operation
                # for swift
                req.headers['X-Copy-From'] = body.get('copy')
                req.body = ''
            else:
                if body.get('metadata'):
                    metadata = body['metadata']
                    for key in metadata:
                        if metadata[key] == '':
                            req.headers[Consts.META_OBJECT_ID + key] = ''
                        else:
                            req.headers[Consts.META_OBJECT_ID + key] = \
                                key + ":" + str(metadata[key])
                else:
                    metadata = {}

                try:
                    req.body = str(body.get('value', ''))
                    req.headers['content-type'] = body.get('mimetype',
                        'text/plain').lower()
                    encoding = body.get('valuetransferencoding', 'utf-8')
                    req.headers[Consts.VALUE_ENCODING] = encoding
                    # if the value is encoded using base64, then
                    # we need to decode it and save as binary
                    if encoding == Consts.ENCODING_BASE64:
                        req.body = base64.decodestring(req.body)
                except KeyError:
                    return get_err_response('InvalidContent')
        else:
            req.headers['content-length'] = '0'

        res = req.get_response(self.app)

        # Deal with the response now.
        # Build the response message body according to CDMI specification
        # If the response status is 201, then we know we have successfully
        # created the object. According to CDMI spec, only send response body
        # when creating new object.
        if res.status_int == 201:
            body = {}
            body['objectType'] = Consts.CDMI_APP_OBJECT
            body['objectName'] = self.object_name
            body['parentURI'] = '/'.join(['', self.cdmi_root,
                                          self.account_name,
                                          self.container_name,
                                          self.parent_name, ''])

            body['capabilitiesURI'] = '/'.join(['', self.cdmi_root,
                                               self.account_name,
                                               self.cdmi_capability_id,
                                               'dataobject/'])

            if env.get('HTTP_X_USE_EXTRA_REQUEST'):
                extra_res = self._put_manifest(env)
                res.status_int = extra_res.status

            body['metadata'] = metadata
            res.body = json.dumps(body, indent=2)
        # Otherwise, no response body should be returned.
        else:
            res.body = ''

        return res
    def PUT(self, env, start_response):
        """ Handle non-CDMI Object update and create request. """

        # First check if the resource exists and if it is a directory
        path = '/' + concat_parts('v1', self.account_name, self.container_name,
                                  self.parent_name, self.object_name)

        exists, headers, body = check_resource(env, 'GET', path, self.logger,
                                               False, None)

        if exists:
            content_type = headers.get('content-type', '')
            content_type = content_type.lower() if content_type else ''
            if content_type.find('application/directory') >= 0:
                return get_err_response('Conflict')
        else:
            path = '/' + concat_parts('v1', self.account_name,
                                      self.container_name)

            query_string = 'delimiter=/&prefix=' + \
                concat_parts(self.parent_name, self.object_name) + '/'

            parent_exists, dummy, body = check_resource(env, 'GET', path,
                                                        self.logger, True,
                                                        query_string)

            if parent_exists:
                try:
                    children = json.loads(body)
                    if len(children) > 0:
                        #No children under, no resource exist
                        return get_err_response('Conflict')
                except ValueError:
                    return get_err_response('InconsistantState')
            else:
                return get_err_response('NoParentContainer')

        # Check if the parent is OK. it should be either a real directory
        # or a virtual directory
        res = self._check_parent(env, start_response)
        if res:
            return res

        try:
            self._handle_part(env)
        except Exception as ex:
            return get_err_response(ex.message)

        try:
            body = self._handle_body(env, False)
        except Exception as ex:
            return get_err_response('InvalidBody')
        else:
            env['CONTENT_TYPE'] = body.get('mimetype', 'text/plain')
            req = Request(env)
            req.body = body.get('value', '')
            req.headers['content-length'] = len(req.body)
            res = req.get_response(self.app)
            if (res.status_int in [201, 204] and
                env.get('HTTP_X_USE_EXTRA_REQUEST')):
                extra_res = self._put_manifest(env)
                res.status_int = extra_res.status
            return res
    def PUT(self, env, start_response):
        """
        Handle Container update and create request
        """

        # First check if the resource exists and if it is a directory
        path = '/' + concat_parts('v1', self.account_name, self.container_name,
                                  self.parent_name, self.object_name)
        exists, headers, dummy = check_resource(env, 'GET', path,
                                                self.logger, False)
        if exists:
            content_type = headers.get('content-type', '')
            content_type = content_type.lower() if content_type else ''
            if (content_type.find('application/directory') < 0 and
                self.object_name):
                return get_err_response('Conflict')
        # Not a top container, so it has to be virtual container
        else:
            res = self._check_parent(env, start_response)
            if res:
                return res

        # Create a new WebOb Request object according to the current request
        req = Request(env)

        # We are creating a container, set the content-type to be
        # application/directory
        req.headers['content-type'] = 'application/directory'

        metadata = {}
        if req.body:
            try:
                body = json.loads(req.body)
            except ValueError:
                return get_err_response('InvalidContent')

            metadata = body.get('metadata')
            if metadata:
                for key in metadata:
                    if metadata[key] == '':
                        req.headers[self.metadata_prefix + key] = ''
                    else:
                        req.headers[self.metadata_prefix + key] = \
                            key + ":" + str(metadata[key])
            else:
                metadata = {}

        # Now set the body to be empty and content-length to 0
        req.body = ''
        req.headers['Content-Length'] = 0

        res = req.get_response(self.app)

        # Deal with the response now.
        # Build the response message body according to CDMI specification
        # if the response status is 201, then we know we have successfully
        # created the container. According to CDMI spec, only send response
        # body when creating new container
        if res.status_int == 201:
            body = {}
            body['objectType'] = Consts.CDMI_APP_CONTAINER
            body['objectName'] = (self.object_name + '/') if self.object_name \
                else (self.container_name + '/')
            if self.object_name:
                body['parentURI'] = '/'.join(['', self.cdmi_root,
                                              self.account_name,
                                              self.container_name,
                                              self.parent_name, ''])
            else:
                body['parentURI'] = '/'.join(['', self.cdmi_root,
                                              self.account_name, ''])

            body['capabilitiesURI'] = '/'.join(['', self.cdmi_root,
                                                self.account_name,
                                                self.cdmi_capability_id,
                                                'container/'])
            body['completionStatus'] = 'Complete'
            body['metadata'] = metadata
            res.body = json.dumps(body, indent=2)
        # Otherwise, no body should be returned.
        else:
            res.body = ''

        return res
    def PUT(self, env, start_response):
        """
        Handle Container update and create request
        """
        # First check if the resource exists and if it is a directory
        path = '/' + concat_parts('v1', self.account_name, self.container_name,
                                  self.parent_name, self.object_name)
        exists, headers, body = check_resource(env, 'GET', path, self.logger,
                                               False, None)
        if exists:
            content_type = headers.get('content-type', '')
            content_type = content_type.lower() if content_type else ''
            if content_type.find('application/directory') >= 0:
                return get_err_response('Conflict')
        else:
            path = '/' + concat_parts('v1', self.account_name,
                                      self.container_name)
            query_string = 'delimiter=/&prefix=' + \
                concat_parts(self.parent_name, self.object_name) + '/'
            parent_exists, dummy, body = check_resource(env, 'GET', path,
                                                        self.logger, True,
                                                        query_string)
            if parent_exists:
                try:
                    children = json.loads(body)
                    if len(children) > 0:
                        # No children under, no resource exist
                        return get_err_response('Conflict')
                except ValueError:
                    return get_err_response('InconsistantState')
            else:
                return get_err_response('NoParentContainer')

        # Check if the parent is OK. it should be either a real directory or
        # a virtual directory
        res = self._check_parent(env, start_response)
        if res:
            return res

        # Create a new WebOb Request object according to the current request
        #if we found X-Object-UploadID in the header, we need know that
        #the request is uploading a piece of a large object, the piece
        #will need to go to the segments folder

        try:
            self._handle_part(env)
        except Exception as ex:
            return get_err_response(ex.message)

        req = Request(env)

        metadata = {}
        if req.body:
            try:
                body = self._handle_body(env, True)
            except Exception:
                return get_err_response('InvalidBody')

            # headling copy object
            if body.get('copy'):
                # add the copy-from header to indicate a copy operation
                # for swift
                req.headers['X-Copy-From'] = body.get('copy')
                req.body = ''
            else:
                if body.get('metadata'):
                    metadata = body['metadata']
                    for key in metadata:
                        if metadata[key] == '':
                            req.headers[Consts.META_OBJECT_ID + key] = ''
                        else:
                            req.headers[Consts.META_OBJECT_ID + key] = \
                                key + ":" + str(metadata[key])
                else:
                    metadata = {}

                try:
                    req.body = str(body.get('value', ''))
                    req.headers['content-type'] = body.get('mimetype',
                        'text/plain').lower()
                    encoding = body.get('valuetransferencoding', '7BIT')
                    req.headers[Consts.VALUE_ENCODING] = encoding
                    # if the value is encoded using base64, then
                    # we need to decode it and save as binary
                    if encoding == Consts.ENCODING_BASE64:
                        req.body = base64.decodestring(req.body)
                except KeyError:
                    return get_err_response('InvalidContent')
        else:
            req.headers['content-length'] = '0'

        res = req.get_response(self.app)

        # Deal with the response now.
        # Build the response message body according to CDMI specification
        # If the response status is 201, then we know we have successfully
        # created the object. According to CDMI spec, only send response body
        # when creating new object.
        if res.status_int == 201:
            body = {}
            body['objectType'] = Consts.CDMI_APP_OBJECT
            body['objectName'] = self.object_name
            if self.parent_name:
                body['parentURI'] = '/'.join(['', self.cdmi_root,
                                          self.account_name,
                                          self.container_name,
                                          self.parent_name, ''])
            else:
                body['parentURI'] = '/'.join(['', self.cdmi_root,
                                          self.account_name,
                                          self.container_name, ''])

            body['capabilitiesURI'] = '/'.join(['', self.cdmi_root,
                                               self.account_name,
                                               self.cdmi_capability_id,
                                               'dataobject/'])

            if env.get('HTTP_X_USE_EXTRA_REQUEST'):
                extra_res = self._put_manifest(env)
                res.status_int = extra_res.status

            body['metadata'] = metadata
            res.body = json.dumps(body, indent=2)
        # Otherwise, no response body should be returned.
        else:
            res.body = ''

        return res
    def PUT(self, env, start_response):
        """ Handle non-CDMI Object update and create request. """

        # First check if the resource exists and if it is a directory
        path = '/' + concat_parts('v1', self.account_name, self.container_name,
                                  self.parent_name, self.object_name)

        exists, headers, body = check_resource(env, 'GET', path, self.logger,
                                               False, None)

        if exists:
            content_type = headers.get('content-type', '')
            content_type = content_type.lower() if content_type else ''
            if content_type.find('application/directory') >= 0:
                return get_err_response('Conflict')
        else:
            path = '/' + concat_parts('v1', self.account_name,
                                      self.container_name)

            query_string = 'delimiter=/&prefix=' + \
                concat_parts(self.parent_name, self.object_name) + '/'

            parent_exists, dummy, body = check_resource(
                env, 'GET', path, self.logger, True, query_string)

            if parent_exists:
                try:
                    children = json.loads(body)
                    if len(children) > 0:
                        #No children under, no resource exist
                        return get_err_response('Conflict')
                except ValueError:
                    return get_err_response('InconsistantState')
            else:
                return get_err_response('NoParentContainer')

        # Check if the parent is OK. it should be either a real directory
        # or a virtual directory
        res = self._check_parent(env, start_response)
        if res:
            return res

        try:
            self._handle_part(env)
        except Exception as ex:
            return get_err_response(ex.message)

        try:
            body = self._handle_body(env, False)
        except Exception as ex:
            return get_err_response('InvalidBody')
        else:
            env['CONTENT_TYPE'] = body.get('mimetype', 'text/plain')
            req = Request(env)
            req.body = body.get('value', '')
            req.headers['content-length'] = len(req.body)
            res = req.get_response(self.app)
            if (res.status_int in [201, 204]
                    and env.get('HTTP_X_USE_EXTRA_REQUEST')):
                extra_res = self._put_manifest(env)
                res.status_int = extra_res.status
            return res