Merge "Symlink doc clean up"
This commit is contained in:
commit
8517a6e572
@ -53,7 +53,7 @@ returns the following values for this header,
|
|||||||
An OPTIONS request to a symlink object will respond with the options for
|
An OPTIONS request to a symlink object will respond with the options for
|
||||||
the symlink only, the request will not be redirected to the target object.
|
the symlink only, the request will not be redirected to the target object.
|
||||||
Therefore, if the symlink's target object is in another container with
|
Therefore, if the symlink's target object is in another container with
|
||||||
cors settings, the response will not reflect the settings.
|
CORS settings, the response will not reflect the settings.
|
||||||
|
|
||||||
|
|
||||||
-----------------
|
-----------------
|
||||||
|
@ -933,7 +933,8 @@ use = egg:swift#listing_formats
|
|||||||
# pipeline.
|
# pipeline.
|
||||||
[filter:symlink]
|
[filter:symlink]
|
||||||
use = egg:swift#symlink
|
use = egg:swift#symlink
|
||||||
# Symlinks can point to other symlinks up to the symloop_max value. If the
|
# Symlinks can point to other symlinks provided the number of symlinks in a
|
||||||
# number of chained symlinks exceeds the limit ``symloop_max`` a 409
|
# chain does not exceed the symloop_max value. If the number of chained
|
||||||
# (HTTPConflict) error response will be produced.
|
# symlinks exceeds the limit symloop_max a 409 (HTTPConflict) error
|
||||||
|
# response will be produced.
|
||||||
# symloop_max = 2
|
# symloop_max = 2
|
||||||
|
@ -16,12 +16,12 @@
|
|||||||
"""
|
"""
|
||||||
Symlink Middleware
|
Symlink Middleware
|
||||||
|
|
||||||
Symlinks are objects stored in Swift that contains a reference to another
|
Symlinks are objects stored in Swift that contain a reference to another
|
||||||
object (hereinafter, this is called "target object"). They are analogous to
|
object (hereinafter, this is called "target object"). They are analogous to
|
||||||
symbolic links in Unix-like operating systems. The existence of a symlink
|
symbolic links in Unix-like operating systems. The existence of a symlink
|
||||||
object does not affect the target object in any way. An important use case is
|
object does not affect the target object in any way. An important use case is
|
||||||
to use a path in one container to access an object in a different container,
|
to use a path in one container to access an object in a different container,
|
||||||
with a different policy. This allows policy cost/performance tradeoffs to be
|
with a different policy. This allows policy cost/performance trade-offs to be
|
||||||
made on individual objects.
|
made on individual objects.
|
||||||
|
|
||||||
Clients create a Swift symlink by performing a zero-length PUT request
|
Clients create a Swift symlink by performing a zero-length PUT request
|
||||||
@ -33,30 +33,30 @@ object in the PUT request process.
|
|||||||
Symlinks must be zero-byte objects. Attempting to PUT a symlink
|
Symlinks must be zero-byte objects. Attempting to PUT a symlink
|
||||||
with a non-empty request body will result in a 400-series error. Also, POST
|
with a non-empty request body will result in a 400-series error. Also, POST
|
||||||
with X-Symlink-Target header always results in a 400-series error. The target
|
with X-Symlink-Target header always results in a 400-series error. The target
|
||||||
object need not exist at symlink-creation time. It is suggested to set the
|
object need not exist at symlink creation time. It is suggested to set the
|
||||||
``Content-Type`` of symlink objects to a distinct value such as
|
``Content-Type`` of symlink objects to a distinct value such as
|
||||||
``application/symlink``.
|
``application/symlink``.
|
||||||
|
|
||||||
A GET/HEAD request to a symlink will resolve in a request to the target
|
A GET/HEAD request to a symlink will result in a request to the target
|
||||||
object referenced by the symlink's ``X-Symlink-Target-Account`` and
|
object referenced by the symlink's ``X-Symlink-Target-Account`` and
|
||||||
``X-Symlink-Target`` headers. The response of the GET/HEAD request will contain
|
``X-Symlink-Target`` headers. The response of the GET/HEAD request will contain
|
||||||
a ``Content-Location`` header with the path location of the target object. A
|
a ``Content-Location`` header with the path location of the target object. A
|
||||||
GET/HEAD request to a symlink with the query parameter ``?symlink=get`` will
|
GET/HEAD request to a symlink with the query parameter ``?symlink=get`` will
|
||||||
resolve in the request targeting the symlink itself.
|
result in the request targeting the symlink itself.
|
||||||
|
|
||||||
A symlink can point to another symlink. Chained symlinks will be traversed
|
A symlink can point to another symlink. Chained symlinks will be traversed
|
||||||
until target is not a symlink. If the number of chained symlinks exceeds the
|
until target is not a symlink. If the number of chained symlinks exceeds the
|
||||||
limit ``symloop_max`` an error response will be produced. The value of
|
limit ``symloop_max`` an error response will be produced. The value of
|
||||||
``symloop_max`` can be defined in the symlink config section of
|
``symloop_max`` can be defined in the symlink config section of
|
||||||
proxy-server.conf. If not specified, the default ``symloop_max`` value is 2. If
|
`proxy-server.conf`. If not specified, the default ``symloop_max`` value is 2.
|
||||||
a value less than 1 is specified, the default value will be used.
|
If a value less than 1 is specified, the default value will be used.
|
||||||
|
|
||||||
A HEAD/GET request to a symlink object behaves as a normal HEAD/GET request
|
A HEAD/GET request to a symlink object behaves as a normal HEAD/GET request
|
||||||
to the target object. Therefore issuing a HEAD request to the symlink will
|
to the target object. Therefore issuing a HEAD request to the symlink will
|
||||||
return the target metadata, and issuing a GET request to the symlink will
|
return the target metadata, and issuing a GET request to the symlink will
|
||||||
return the data and metadata of the target object. Only when a GET/HEAD
|
return the data and metadata of the target object. To return the symlink
|
||||||
request sent to a symlink object with the ``?symlink=get`` query string
|
metadata (with its empty body) a GET/HEAD request with the ``?symlink=get``
|
||||||
will return the symlink metadata with empty body.
|
query parameter must be sent to a symlink object.
|
||||||
|
|
||||||
A POST request to a symlink will result in a 307 TemporaryRedirect response.
|
A POST request to a symlink will result in a 307 TemporaryRedirect response.
|
||||||
The response will contain a ``Location`` header with the path of the target
|
The response will contain a ``Location`` header with the path of the target
|
||||||
@ -74,7 +74,7 @@ parameter ``?symlink=get`` will copy the symlink itself.
|
|||||||
|
|
||||||
An OPTIONS request to a symlink will respond with the options for the symlink
|
An OPTIONS request to a symlink will respond with the options for the symlink
|
||||||
only, the request will not be redirected to the target object. Please note that
|
only, the request will not be redirected to the target object. Please note that
|
||||||
if the symlink's target object is in another container with cors settings, the
|
if the symlink's target object is in another container with CORS settings, the
|
||||||
response will not reflect the settings.
|
response will not reflect the settings.
|
||||||
|
|
||||||
Tempurls can be used to GET/HEAD symlink objects, but PUT is not allowed and
|
Tempurls can be used to GET/HEAD symlink objects, but PUT is not allowed and
|
||||||
@ -87,10 +87,11 @@ error. The account level tempurl will allow cross container symlinks.
|
|||||||
If a symlink object is overwritten while it is in a versioned container, the
|
If a symlink object is overwritten while it is in a versioned container, the
|
||||||
symlink object itself is versioned, not the referenced object.
|
symlink object itself is versioned, not the referenced object.
|
||||||
|
|
||||||
A GET request to a container which contains symlinks will respond with
|
A GET request with query parameter ``?format=json`` or ``?format=xml`` to a
|
||||||
additional information ``symlink_path`` for each symlink objects.
|
container which contains symlinks will respond with additional information
|
||||||
``symlink_path`` information are target path strings of the symlinks. Clients
|
``symlink_path`` for each symlink object in the container listing. The
|
||||||
can differentiate symlinks and other objects by this function.
|
``symlink_path`` value is the target path of the symlink. Clients can
|
||||||
|
differentiate symlinks and other objects by this function.
|
||||||
|
|
||||||
Errors
|
Errors
|
||||||
|
|
||||||
@ -188,11 +189,13 @@ def _check_symlink_header(req):
|
|||||||
:param req: HTTP request object
|
:param req: HTTP request object
|
||||||
:raise: HTTPPreconditionFailed if x-symlink-target value
|
:raise: HTTPPreconditionFailed if x-symlink-target value
|
||||||
is not well formatted.
|
is not well formatted.
|
||||||
|
:raise: HTTPBadRequest if the x-symlink-target value points to the request
|
||||||
|
path.
|
||||||
"""
|
"""
|
||||||
# N.B. check_path_header doesn't assert the leading slash and
|
# N.B. check_path_header doesn't assert the leading slash and
|
||||||
# copy middleware may accpet the format. In the symlink, API
|
# copy middleware may accept the format. In the symlink, API
|
||||||
# says apparently to use "container/object" format so add the
|
# says apparently to use "container/object" format so add the
|
||||||
# validation fist, here.
|
# validation first, here.
|
||||||
if unquote(req.headers[TGT_OBJ_SYMLINK_HDR]).startswith('/'):
|
if unquote(req.headers[TGT_OBJ_SYMLINK_HDR]).startswith('/'):
|
||||||
raise HTTPPreconditionFailed(
|
raise HTTPPreconditionFailed(
|
||||||
body='X-Symlink-Target header must be of the '
|
body='X-Symlink-Target header must be of the '
|
||||||
@ -225,7 +228,7 @@ def _check_symlink_header(req):
|
|||||||
|
|
||||||
def symlink_usermeta_to_sysmeta(headers):
|
def symlink_usermeta_to_sysmeta(headers):
|
||||||
"""
|
"""
|
||||||
Helper fucntion to translate from X-Symlink-Target and
|
Helper function to translate from X-Symlink-Target and
|
||||||
X-Symlink-Target-Account to X-Object-Sysmeta-Symlink-Target
|
X-Symlink-Target-Account to X-Object-Sysmeta-Symlink-Target
|
||||||
and X-Object-Sysmeta-Symlink-Target-Account.
|
and X-Object-Sysmeta-Symlink-Target-Account.
|
||||||
|
|
||||||
@ -244,7 +247,7 @@ def symlink_usermeta_to_sysmeta(headers):
|
|||||||
|
|
||||||
def symlink_sysmeta_to_usermeta(headers):
|
def symlink_sysmeta_to_usermeta(headers):
|
||||||
"""
|
"""
|
||||||
Helper fucntion to translate from X-Object-Sysmeta-Symlink-Target and
|
Helper function to translate from X-Object-Sysmeta-Symlink-Target and
|
||||||
X-Object-Sysmeta-Symlink-Target-Account to X-Symlink-Target and
|
X-Object-Sysmeta-Symlink-Target-Account to X-Symlink-Target and
|
||||||
X-Sysmeta-Symlink-Target-Account
|
X-Sysmeta-Symlink-Target-Account
|
||||||
|
|
||||||
@ -263,12 +266,15 @@ def symlink_sysmeta_to_usermeta(headers):
|
|||||||
class SymlinkContainerContext(WSGIContext):
|
class SymlinkContainerContext(WSGIContext):
|
||||||
def __init__(self, wsgi_app, logger):
|
def __init__(self, wsgi_app, logger):
|
||||||
super(SymlinkContainerContext, self).__init__(wsgi_app)
|
super(SymlinkContainerContext, self).__init__(wsgi_app)
|
||||||
self.app = wsgi_app
|
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
|
|
||||||
def handle_container(self, req, start_response):
|
def handle_container(self, req, start_response):
|
||||||
"""
|
"""
|
||||||
Handle container requests.
|
Handle container requests.
|
||||||
|
|
||||||
|
:param req: a :class:`~swift.common.swob.Request`
|
||||||
|
:param start_response: start_response function
|
||||||
|
|
||||||
:return: Response Iterator after start_response called.
|
:return: Response Iterator after start_response called.
|
||||||
"""
|
"""
|
||||||
app_resp = self._app_call(req.environ)
|
app_resp = self._app_call(req.environ)
|
||||||
@ -326,11 +332,10 @@ class SymlinkObjectContext(WSGIContext):
|
|||||||
|
|
||||||
def __init__(self, wsgi_app, logger, symloop_max):
|
def __init__(self, wsgi_app, logger, symloop_max):
|
||||||
super(SymlinkObjectContext, self).__init__(wsgi_app)
|
super(SymlinkObjectContext, self).__init__(wsgi_app)
|
||||||
self.app = wsgi_app
|
|
||||||
self.symloop_max = symloop_max
|
self.symloop_max = symloop_max
|
||||||
self.logger = logger
|
self.logger = logger
|
||||||
# N.B. _loop_count and _last_target_path are used to keep
|
# N.B. _loop_count and _last_target_path are used to keep
|
||||||
# the statement in the _recursive_get. Hence it should not be touched
|
# the statement in the _recursive_get. Hence they should not be touched
|
||||||
# from other resources.
|
# from other resources.
|
||||||
self._loop_count = 0
|
self._loop_count = 0
|
||||||
self._last_target_path = None
|
self._last_target_path = None
|
||||||
@ -342,7 +347,6 @@ class SymlinkObjectContext(WSGIContext):
|
|||||||
:param req: HTTP GET or HEAD object request with param ?symlink=get
|
:param req: HTTP GET or HEAD object request with param ?symlink=get
|
||||||
:returns: Response Iterator
|
:returns: Response Iterator
|
||||||
"""
|
"""
|
||||||
|
|
||||||
resp = self._app_call(req.environ)
|
resp = self._app_call(req.environ)
|
||||||
response_header_dict = HeaderKeyDict(self._response_headers)
|
response_header_dict = HeaderKeyDict(self._response_headers)
|
||||||
symlink_sysmeta_to_usermeta(response_header_dict)
|
symlink_sysmeta_to_usermeta(response_header_dict)
|
||||||
@ -463,7 +467,7 @@ class SymlinkObjectContext(WSGIContext):
|
|||||||
the stored object is a symlink or not.
|
the stored object is a symlink or not.
|
||||||
|
|
||||||
:param req: HTTP POST object request
|
:param req: HTTP POST object request
|
||||||
:returns: HTTPTemporaryRedirect if POSTing to a symlink.
|
:raises: HTTPTemporaryRedirect if POSTing to a symlink.
|
||||||
:returns: Response Iterator
|
:returns: Response Iterator
|
||||||
"""
|
"""
|
||||||
if TGT_OBJ_SYMLINK_HDR in req.headers:
|
if TGT_OBJ_SYMLINK_HDR in req.headers:
|
||||||
@ -493,7 +497,11 @@ class SymlinkObjectContext(WSGIContext):
|
|||||||
|
|
||||||
def handle_object(self, req, start_response):
|
def handle_object(self, req, start_response):
|
||||||
"""
|
"""
|
||||||
Handle object requests
|
Handle object requests.
|
||||||
|
|
||||||
|
:param req: a :class:`~swift.common.swob.Request`
|
||||||
|
:param start_response: start_response function
|
||||||
|
:returns: Response Iterator after start_response has been called
|
||||||
"""
|
"""
|
||||||
if req.method in ('GET', 'HEAD'):
|
if req.method in ('GET', 'HEAD'):
|
||||||
# if GET request came from versioned writes, then it should get
|
# if GET request came from versioned writes, then it should get
|
||||||
@ -522,10 +530,10 @@ class SymlinkMiddleware(object):
|
|||||||
"""
|
"""
|
||||||
Middleware that implements symlinks.
|
Middleware that implements symlinks.
|
||||||
|
|
||||||
Symlinks are objects stored in Swift that contains a reference to another
|
Symlinks are objects stored in Swift that contain a reference to another
|
||||||
object (i.e., the target object). An important use case is to use a path in
|
object (i.e., the target object). An important use case is to use a path in
|
||||||
one container to access an object in a different container, with a
|
one container to access an object in a different container, with a
|
||||||
different policy. This allows policy cost/performance tradeoffs to be made
|
different policy. This allows policy cost/performance trade-offs to be made
|
||||||
on individual objects.
|
on individual objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user