~ubuntu-branches/ubuntu/trusty/swift/trusty-updates

« back to all changes in this revision

Viewing changes to swift/proxy/controllers/obj.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2013-01-28 09:40:30 UTC
  • mfrom: (1.2.16)
  • Revision ID: package-import@ubuntu.com-20130128094030-aetz57x2qz9ye2d4
Tags: 1.7.6-0ubuntu1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#   These shenanigans are to ensure all related objects can be garbage
25
25
# collected. We've seen objects hang around forever otherwise.
26
26
 
27
 
try:
28
 
    import simplejson as json
29
 
except ImportError:
30
 
    import json
 
27
import itertools
31
28
import mimetypes
32
29
import re
33
30
import time
41
38
from eventlet.timeout import Timeout
42
39
 
43
40
from swift.common.utils import ContextPool, normalize_timestamp, \
44
 
    config_true_value, public
 
41
    config_true_value, public, json
45
42
from swift.common.bufferedhttp import http_connect
46
43
from swift.common.constraints import check_metadata, check_object_creation, \
47
44
    CONTAINER_LISTING_LIMIT, MAX_FILE_SIZE
247
244
        self.object_name = unquote(object_name)
248
245
 
249
246
    def _listing_iter(self, lcontainer, lprefix, env):
 
247
        for page in self._listing_pages_iter(lcontainer, lprefix, env):
 
248
            for item in page:
 
249
                yield item
 
250
 
 
251
    def _listing_pages_iter(self, lcontainer, lprefix, env):
250
252
        lpartition, lnodes = self.app.container_ring.get_nodes(
251
253
            self.account_name, lcontainer)
252
254
        marker = ''
278
280
            if not sublisting:
279
281
                break
280
282
            marker = sublisting[-1]['name']
281
 
            for obj in sublisting:
282
 
                yield obj
 
283
            yield sublisting
 
284
 
 
285
    def _remaining_items(self, listing_iter):
 
286
        """
 
287
        Returns an item-by-item iterator for a page-by-page iterator
 
288
        of item listings.
 
289
 
 
290
        Swallows listing-related errors; this iterator is only used
 
291
        after we've already started streaming a response to the
 
292
        client, and so if we start getting errors from the container
 
293
        servers now, it's too late to send an error to the client, so
 
294
        we just quit looking for segments.
 
295
        """
 
296
        try:
 
297
            for page in listing_iter:
 
298
                for item in page:
 
299
                    yield item
 
300
        except ListingIterNotFound:
 
301
            pass
 
302
        except ListingIterError:
 
303
            pass
 
304
        except ListingIterNotAuthorized:
 
305
            pass
283
306
 
284
307
    def is_good_source(self, src):
285
308
        """
316
339
            lcontainer = unquote(lcontainer)
317
340
            lprefix = unquote(lprefix)
318
341
            try:
319
 
                listing = list(self._listing_iter(lcontainer, lprefix,
320
 
                               req.environ))
 
342
                pages_iter = iter(self._listing_pages_iter(lcontainer, lprefix,
 
343
                                                           req.environ))
 
344
                listing_page1 = pages_iter.next()
 
345
                listing = itertools.chain(listing_page1,
 
346
                                          self._remaining_items(pages_iter))
321
347
            except ListingIterNotFound:
322
348
                return HTTPNotFound(request=req)
323
349
            except ListingIterNotAuthorized, err:
324
350
                return err.aresp
325
351
            except ListingIterError:
326
352
                return HTTPServerError(request=req)
 
353
            except StopIteration:
 
354
                listing_page1 = listing = ()
327
355
 
328
 
            if len(listing) > CONTAINER_LISTING_LIMIT:
 
356
            if len(listing_page1) >= CONTAINER_LISTING_LIMIT:
329
357
                resp = Response(headers=resp.headers, request=req,
330
358
                                conditional_response=True)
331
359
                if req.method == 'HEAD':
344
372
                    return head_response
345
373
                else:
346
374
                    resp.app_iter = SegmentedIterable(
347
 
                        self, lcontainer,
348
 
                        self._listing_iter(lcontainer, lprefix, req.environ),
349
 
                        resp)
 
375
                        self, lcontainer, listing, resp)
350
376
 
351
377
            else:
352
378
                # For objects with a reasonable number of segments, we'll serve
353
379
                # them with a set content-length and computed etag.
354
380
                if listing:
 
381
                    listing = list(listing)
355
382
                    content_length = sum(o['bytes'] for o in listing)
356
383
                    last_modified = max(o['last_modified'] for o in listing)
357
384
                    last_modified = datetime(*map(int, re.split('[^\d]',