def srv_pullobsmarkers(repo, proto, others): """serves a binary stream of markers. Serves relevant to changeset between heads and common. The stream is prefix by a -string- representation of an integer. This integer is the size of the stream.""" opts = wireproto.options('', ['heads', 'common'], others) for k, v in opts.iteritems(): if k in ('heads', 'common'): opts[k] = wireproto.decodelist(v) obsdata = _getobsmarkersstream(repo, **opts) finaldata = StringIO() obsdata = obsdata.getvalue() finaldata.write('%20i' % len(obsdata)) finaldata.write(obsdata) finaldata.seek(0) return wireproto.streamres(proto.groupchunks(finaldata))
def getbfile(repo, proto, sha): """getbfile retrieves a bfile from the repository-local cache or system cache.""" filename = bfutil.findfile(repo, sha) if not filename: raise util.Abort(_('requested bfile %s not present in cache') % sha) f = open(filename, 'rb') length = os.fstat(f.fileno())[6] # since we can't set an HTTP content-length header here, and mercurial core # provides no way to give the length of a streamres (and reading the entire # file into RAM would be ill-advised), we just send the length on the first # line of the response, like the ssh proto does for string responses. def generator(): yield '%d\n' % length for chunk in f: yield chunk return wireproto.streamres(generator())
def getlfile(repo, proto, sha): '''Retrieve a largefile from the repository-local cache or system cache.''' filename = lfutil.findfile(repo, sha) if not filename: raise util.Abort(_('requested largefile %s not present in cache') % sha) f = open(filename, 'rb') length = os.fstat(f.fileno())[6] # Since we can't set an HTTP content-length header here, and # Mercurial core provides no way to give the length of a streamres # (and reading the entire file into RAM would be ill-advised), we # just send the length on the first line of the response, like the # ssh proto does for string responses. def generator(): yield '%d\n' % length for chunk in util.filechunkiter(f): yield chunk return wireproto.streamres(generator())
def getfiles(repo, proto): """A server api for requesting particular versions of particular files. """ if shallowrepo.requirement in repo.requirements: raise util.Abort(_('cannot fetch remote files from shallow repo')) def streamer(): fin = proto.fin opener = repo.sopener cachepath = repo.ui.config("remotefilelog", "servercachepath") if not cachepath: cachepath = os.path.join(repo.path, "remotefilelogcache") # everything should be user & group read/writable oldumask = os.umask(0o002) try: while True: request = fin.readline()[:-1] if not request: break node = bin(request[:40]) if node == nullid: yield '0\n' continue path = request[40:] filecachepath = os.path.join(cachepath, path, hex(node)) if not os.path.exists(filecachepath): filectx = repo.filectx(path, fileid=node) if filectx.node() == nullid: repo.changelog = changelog.changelog(repo.sopener) filectx = repo.filectx(path, fileid=node) text = createfileblob(filectx) text = lz4.compressHC(text) dirname = os.path.dirname(filecachepath) if not os.path.exists(dirname): os.makedirs(dirname) try: with open(filecachepath, "w") as f: f.write(text) except IOError: # Don't abort if the user only has permission to read, # and not write. pass else: with open(filecachepath, "r") as f: text = f.read() yield '%d\n%s' % (len(text), text) # it would be better to only flush after processing a whole batch # but currently we don't know if there are more requests coming proto.fout.flush() finally: os.umask(oldumask) return wireproto.streamres(streamer())