Merge "Symlink doc clean up"

This commit is contained in:
Zuul 2017-12-15 02:33:22 +00:00 committed by Gerrit Code Review
commit 8517a6e572
3 changed files with 40 additions and 31 deletions

View File

@ -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.
----------------- -----------------

View File

@ -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

View File

@ -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.
""" """