示例#1
0
    def get(self, name):
        """Catalog get handler.

    Args:
      name: string catalog name to get.

    Returns:
      A webapp.Response() response.
    """
        auth.DoAnyAuth()

        catalog = models.Catalog.MemcacheWrappedGet(name)
        if not catalog:
            self.response.set_status(httplib.NOT_FOUND)
            return

        header_date_str = self.request.headers.get('If-Modified-Since', '')
        if not handlers.IsClientResourceExpired(catalog.mtime,
                                                header_date_str):
            self.response.set_status(httplib.NOT_MODIFIED)
            return

        self.response.headers['Last-Modified'] = catalog.mtime.strftime(
            handlers.HEADER_DATE_FORMAT)

        self.response.headers['Content-Type'] = 'text/xml; charset=utf-8'
        self.response.out.write(catalog.plist_xml)
示例#2
0
文件: applesus.py 项目: smusa/simian
  def get(self, client_id_str=''):
    """AppleSUS get handler.

    Args:
      name: str, optional, catalog name to get.
    """
    session = auth.DoAnyAuth()
    client_id = handlers.GetClientIdForRequest(
            self.request, session=session, client_id_str=client_id_str)

    # get only major.minor os_version, stripping miniscule versioning.
    # i.e. 10.6.6 becomes 10.6, 10.23.6.x.x becomes 10.23
    full_os_version = client_id.get('os_version', '') or ''
    os_version = '.'.join(full_os_version.split('.', 2)[:2])
    track = client_id.get('track', 'stable')
    catalog_name = '%s_%s' % (os_version, track)

    catalog = models.AppleSUSCatalog.MemcacheWrappedGet(catalog_name)
    if not catalog:
      logging.warning('Apple SUS catalog not found: %s', catalog_name)
      self.response.set_status(404)
      return

    header_date_str = self.request.headers.get('If-Modified-Since', '')
    catalog_date = catalog.mtime
    if handlers.IsClientResourceExpired(catalog_date, header_date_str):
      self.response.headers['Last-Modified'] = catalog_date.strftime(
          handlers.HEADER_DATE_FORMAT)
      self.response.headers['Content-Type'] = 'text/xml; charset=utf-8'
      self.response.out.write(catalog.plist)
    else:
      self.response.set_status(304)
示例#3
0
    def get(self, msg='', unused_provided_by_softwareupdate=''):
        """AppleSUS get handler.

    Args:
      name: str, catalog name to get.
      unused_provided_by_softwareupdate: Apple softwareupdate appends filename
        to our url.
    """
        if msg:
            # Clients first POST to this handler and receive a URL with an embedded,
            # encrypted cookie-set containing an Auth1Token.  When GET is called on
            # this URL, we must decode and unpack the cookie/Auth1Token, and set
            # the HTTP_COOKIE environment variable for DoMunkiAuth to validate.
            try:
                d = _DecodeMsg(msg)
            except ValueError:
                self.response.set_status(httplib.BAD_REQUEST)
                return
            os.environ['HTTP_COOKIE'] = str(d['cookies'])
            self.request.headers[MUNKI_CLIENT_ID_HEADER_KEY] = d['header']

        session = gaeserver.DoMunkiAuth(require_level=gaeserver.LEVEL_APPLESUS)
        client_id = handlers.GetClientIdForRequest(self.request,
                                                   session=session)

        # get only major.minor os_version, stripping miniscule versioning.
        # i.e. 10.6.6 becomes 10.6, 10.23.6.x.x becomes 10.23
        full_os_version = client_id.get('os_version', '')
        os_version = '.'.join(full_os_version.split('.', 2)[:2])
        track = client_id.get('track', 'stable')
        catalog_name = '%s_%s' % (os_version, track)

        catalog = models.AppleSUSCatalog.MemcacheWrappedGet(catalog_name)
        if not catalog:
            logging.warning('Apple SUS catalog not found: %s', catalog_name)
            self.response.set_status(httplib.NOT_FOUND)
            return

        header_date_str = self.request.headers.get('If-Modified-Since', '')
        catalog_date = catalog.mtime
        if handlers.IsClientResourceExpired(catalog_date, header_date_str):
            self.response.headers['Last-Modified'] = catalog_date.strftime(
                handlers.HEADER_DATE_FORMAT)
            self.response.headers['Content-Type'] = 'text/xml; charset=utf-8'
            self.response.out.write(catalog.plist)
        else:
            self.response.set_status(httplib.NOT_MODIFIED)
示例#4
0
文件: pkgs.py 项目: smusa/simian
    def get(self, filename):
        """GET

    Args:
      filename: str, package filename like 'foo.dmg'
    Returns:
      None if a blob is being returned,
      or a response object
    """
        auth_return = auth.DoAnyAuth()
        if hasattr(auth_return, 'email'):
            email = auth_return.email()
            if not auth.IsAdminUser(email) and not auth.IsSupportUser(email):
                raise auth.IsAdminMismatch

        filename = urllib.unquote(filename)
        pkg = models.PackageInfo.MemcacheWrappedGet(filename)

        if pkg is None or not pkg.blobstore_key:
            self.error(404)
            return

        if common.IsPanicModeNoPackages():
            self.error(503)
            return

        # Get the Blobstore BlobInfo for this package; memcache wrapped.
        memcache_key = 'blobinfo_%s' % filename
        blob_info = memcache.get(memcache_key)
        if not blob_info:
            blob_info = blobstore.BlobInfo.get(pkg.blobstore_key)
            if blob_info:
                memcache.set(memcache_key, blob_info,
                             300)  # cache for 5 minutes.
            else:
                logging.critical(
                    'Failure fetching BlobInfo for %s. Verify the blob exists: %s',
                    pkg.filename, pkg.blobstore_key)
                self.error(404)
                return

        header_date_str = self.request.headers.get('If-Modified-Since', '')
        etag_nomatch_str = self.request.headers.get('If-None-Match', 0)
        etag_match_str = self.request.headers.get('If-Match', 0)
        pkg_date = blob_info.creation
        pkg_size_bytes = blob_info.size

        # TODO(user): The below can be simplified once all of our clients
        # have ETag values set on the filesystem for these files.  The
        # parsing of If-Modified-Since could be removed.  Removing it prematurely
        # will cause a re-download of all packages on all clients for 1 iteration
        # until they all have ETag values.

        # Reduce complexity of elif conditional below.
        # If an If-None-Match: ETag is supplied, don't worry about a
        # missing file modification date -- the ETag supplies everything needed.
        if etag_nomatch_str and not header_date_str:
            resource_expired = False
        else:
            resource_expired = handlers.IsClientResourceExpired(
                pkg_date, header_date_str)

        # Client supplied If-Match: etag, but that etag does not match current
        # etag.  return 412.
        if (etag_match_str and pkg.pkgdata_sha256
                and etag_match_str != pkg.pkgdata_sha256):
            self.response.set_status(412)

        # Client supplied no etag or If-No-Match: etag, and the etag did not
        # match, or the client's file is older than the mod time of this package.
        elif ((etag_nomatch_str and pkg.pkgdata_sha256
               and etag_nomatch_str != pkg.pkgdata_sha256)
              or resource_expired):
            self.response.headers['Content-Disposition'] = str(
                'attachment; filename=%s' % filename)
            # header date empty or package has changed, send blob with last-mod date.
            if pkg.pkgdata_sha256:
                self.response.headers['ETag'] = str(pkg.pkgdata_sha256)
            self.response.headers['Last-Modified'] = pkg_date.strftime(
                handlers.HEADER_DATE_FORMAT)
            self.response.headers['X-Download-Size'] = str(pkg_size_bytes)
            self.send_blob(pkg.blobstore_key)
        else:
            # Client doesn't need to do anything, current version is OK based on
            # ETag and/or last modified date.
            if pkg.pkgdata_sha256:
                self.response.headers['ETag'] = str(pkg.pkgdata_sha256)
            self.response.set_status(304)
示例#5
0
 def testPackageModifiedWherePackageDateNewer(self):
     """Tests IsClientResourceExpired() with matching header str date."""
     header_dt_str = 'Mon, 01 Jan 1930 01:00:00 GMT'
     dt = datetime.datetime(2010, 10, 06, 03, 23, 34)  # later date
     self.assertTrue(handlers.IsClientResourceExpired(dt, header_dt_str))
示例#6
0
 def testPackageModifiedMatchingDate(self):
     """Tests IsClientResourceExpired() with matching header str date."""
     header_dt_str = 'Wed, 06 Oct 2010 03:23:34 GMT'
     dt = datetime.datetime(2010, 10, 06, 03, 23, 34)  # same date
     self.assertFalse(handlers.IsClientResourceExpired(dt, header_dt_str))
示例#7
0
 def testPackageModifiedWithInvalidDate(self):
     """Tests IsClientResourceExpired() with non-parsable header str date."""
     self.assertTrue(
         handlers.IsClientResourceExpired(None, 'date will not parse'))
示例#8
0
 def testIsClientResourceExpiredWithEmptyDate(self):
     """Tests IsClientResourceExpired() with empty header str date."""
     self.assertTrue(handlers.IsClientResourceExpired(None, ''))