docs: def get_file(self,
                   path,
                   dest='',
                   makedirs=False,
                   saltenv='base',
                   gzip=None,
                   cachedir=None):
          '''
          Get a single file from the salt-master
          path must be a salt server location, aka, salt://path/to/file, if
          dest is omitted, then the downloaded file will be placed in the minion
          cache
          '''
          path, senv = salt.utils.url.split_env(path)
          if senv:
              saltenv = senv
  
          if not salt.utils.platform.is_windows():
              hash_server, stat_server = self.hash_and_stat_file(path, saltenv)
              try:
                  mode_server = stat_server[0]
              except (IndexError, TypeError):
                  mode_server = None
          else:
              hash_server = self.hash_file(path, saltenv)
              mode_server = None
  
          # Check if file exists on server, before creating files and
          # directories
          if hash_server == '':
              log.debug(
                  'Could not find file \'%s\' in saltenv \'%s\'',
                  path, saltenv
              )
              return False
  
          # If dest is a directory, rewrite dest with filename
          if dest is not None \
                  and (os.path.isdir(dest) or dest.endswith(('/', '\\'))):
              dest = os.path.join(dest, os.path.basename(path))
              log.debug(
                  'In saltenv \'%s\', \'%s\' is a directory. Changing dest to '
                  '\'%s\'', saltenv, os.path.dirname(dest), dest
              )
  
          # Hash compare local copy with master and skip download
          # if no difference found.
          dest2check = dest
          if not dest2check:
              rel_path = self._check_proto(path)
  
              log.debug(
                  'In saltenv \'%s\', looking at rel_path \'%s\' to resolve '
                  '\'%s\'', saltenv, rel_path, path
              )
              with self._cache_loc(
                      rel_path, saltenv, cachedir=cachedir) as cache_dest:
                  dest2check = cache_dest
  
          log.debug(
              'In saltenv \'%s\', ** considering ** path \'%s\' to resolve '
              '\'%s\'', saltenv, dest2check, path
          )
  
          if dest2check and os.path.isfile(dest2check):
              if not salt.utils.platform.is_windows():
                  hash_local, stat_local = \
                      self.hash_and_stat_file(dest2check, saltenv)
                  try:
                      mode_local = stat_local[0]
                  except (IndexError, TypeError):
                      mode_local = None
              else:
                  hash_local = self.hash_file(dest2check, saltenv)
                  mode_local = None
  
              if hash_local == hash_server:
                  return dest2check
  
          log.debug(
              'Fetching file from saltenv \'%s\', ** attempting ** \'%s\'',
              saltenv, path
          )
          d_tries = 0
          transport_tries = 0
          path = self._check_proto(path)
          load = {'path': path,
                  'saltenv': saltenv,
                  'cmd': '_serve_file'}
          if gzip:
              gzip = int(gzip)
              load['gzip'] = gzip
  
          fn_ = None
          if dest:
              destdir = os.path.dirname(dest)
              if not os.path.isdir(destdir):
                  if makedirs:
                      try:
                          os.makedirs(destdir)
                      except OSError as exc:
                          if exc.errno != errno.EEXIST:  # ignore if it was there already
                              raise
                  else:
                      return False
              # We need an open filehandle here, that's why we're not using a
              # with clause:
              fn_ = salt.utils.files.fopen(dest, 'wb+')  # pylint: disable=resource-leakage
          else:
              log.debug('No dest file found')
  
          while True:
              if not fn_:
                  load['loc'] = 0
              else:
                  load['loc'] = fn_.tell()
              data = self.channel.send(load, raw=True)
              if six.PY3:
                  # Sometimes the source is local (eg when using
                  # 'salt.fileserver.FSChan'), in which case the keys are
                  # already strings. Sometimes the source is remote, in which
                  # case the keys are bytes due to raw mode. Standardize on
                  # strings for the top-level keys to simplify things.
                  data = decode_dict_keys_to_str(data)
              try:
                  if not data['data']:
                      if not fn_ and data['dest']:
                          # This is a 0 byte file on the master
                          with self._cache_loc(
                                  data['dest'],
                                  saltenv,
                                  cachedir=cachedir) as cache_dest:
                              dest = cache_dest
                              with salt.utils.files.fopen(cache_dest, 'wb+') as ofile:
                                  ofile.write(data['data'])
                      if 'hsum' in data and d_tries < 3:
                          # Master has prompted a file verification, if the
                          # verification fails, re-download the file. Try 3 times
                          d_tries += 1
                          hsum = salt.utils.hashutils.get_hash(dest, salt.utils.stringutils.to_str(data.get('hash_type', b'md5')))
                          if hsum != data['hsum']:
                              log.warning(
                                  'Bad download of file %s, attempt %d of 3',
                                  path, d_tries
                              )
                              continue
                      break
                  if not fn_:
                      with self._cache_loc(
                              data['dest'],
                              saltenv,
                              cachedir=cachedir) as cache_dest:
                          dest = cache_dest
                          # If a directory was formerly cached at this path, then
                          # remove it to avoid a traceback trying to write the file
                          if os.path.isdir(dest):
                              salt.utils.files.rm_rf(dest)
                          fn_ = salt.utils.atomicfile.atomic_open(dest, 'wb+')
                  if data.get('gzip', None):
                      data = salt.utils.gzip_util.uncompress(data['data'])
                  else:
                      data = data['data']
                  if six.PY3 and isinstance(data, str):
                      data = data.encode()
                  fn_.write(data)
              except (TypeError, KeyError) as exc:
                  try:
                      data_type = type(data).__name__
                  except AttributeError:
                      # Shouldn't happen, but don't let this cause a traceback.
                      data_type = six.text_type(type(data))
                  transport_tries += 1
                  log.warning(
                      'Data transport is broken, got: %s, type: %s, '
                      'exception: %s, attempt %d of 3',
                      data, data_type, exc, transport_tries
                  )
                  self._refresh_channel()
                  if transport_tries > 3:
                      log.error(
                          'Data transport is broken, got: %s, type: %s, '
                          'exception: %s, retry attempts exhausted',
                          data, data_type, exc
                      )
                      break
  
          if fn_:
              fn_.close()
              log.info(
                  'Fetching file from saltenv \'%s\', ** done ** \'%s\'',
                  saltenv, path
              )
          else:
              log.debug(
                  'In saltenv \'%s\', we are ** missing ** the file \'%s\'',
                  saltenv, path
              )
  
          return dest