Mercurial > public > mercurial-scm > hg
comparison mercurial/hgweb/hgweb_mod.py @ 4228:c52b7176af94
hgweb: handle IOErrors and OSErrors during unbundle
This allows the client to display a reasonable message to the user
(e.g. "Permission denied: .hg/lock"), instead of the current
"<url> does not appear to be an hg repository".
author | Alexis S. L. Carvalho <alexis@cecm.usp.br> |
---|---|
date | Fri, 16 Mar 2007 00:22:55 -0300 |
parents | f5b9edf3390b |
children | 0d51eb296fb9 3f2e334937ce |
comparison
equal
deleted
inserted
replaced
4227:f5b9edf3390b | 4228:c52b7176af94 |
---|---|
1097 try: | 1097 try: |
1098 length = int(req.env['CONTENT_LENGTH']) | 1098 length = int(req.env['CONTENT_LENGTH']) |
1099 for s in util.filechunkiter(req, limit=length): | 1099 for s in util.filechunkiter(req, limit=length): |
1100 fp.write(s) | 1100 fp.write(s) |
1101 | 1101 |
1102 lock = self.repo.lock() | |
1103 try: | 1102 try: |
1104 if not check_heads(): | 1103 lock = self.repo.lock() |
1105 req.write('0\n') | 1104 try: |
1106 req.write(_('unsynced changes\n')) | 1105 if not check_heads(): |
1107 return | 1106 req.write('0\n') |
1108 | 1107 req.write(_('unsynced changes\n')) |
1109 fp.seek(0) | 1108 return |
1110 header = fp.read(6) | 1109 |
1111 if not header.startswith("HG"): | 1110 fp.seek(0) |
1112 # old client with uncompressed bundle | 1111 header = fp.read(6) |
1113 def generator(f): | 1112 if not header.startswith("HG"): |
1114 yield header | 1113 # old client with uncompressed bundle |
1115 for chunk in f: | 1114 def generator(f): |
1116 yield chunk | 1115 yield header |
1117 elif not header.startswith("HG10"): | 1116 for chunk in f: |
1118 req.write("0\n") | 1117 yield chunk |
1119 req.write(_("unknown bundle version\n")) | 1118 elif not header.startswith("HG10"): |
1120 return | 1119 req.write("0\n") |
1121 elif header == "HG10GZ": | 1120 req.write(_("unknown bundle version\n")) |
1122 def generator(f): | 1121 return |
1123 zd = zlib.decompressobj() | 1122 elif header == "HG10GZ": |
1124 for chunk in f: | 1123 def generator(f): |
1125 yield zd.decompress(chunk) | 1124 zd = zlib.decompressobj() |
1126 elif header == "HG10BZ": | 1125 for chunk in f: |
1127 def generator(f): | 1126 yield zd.decompress(chunk) |
1128 zd = bz2.BZ2Decompressor() | 1127 elif header == "HG10BZ": |
1129 zd.decompress("BZ") | 1128 def generator(f): |
1130 for chunk in f: | 1129 zd = bz2.BZ2Decompressor() |
1131 yield zd.decompress(chunk) | 1130 zd.decompress("BZ") |
1132 elif header == "HG10UN": | 1131 for chunk in f: |
1133 def generator(f): | 1132 yield zd.decompress(chunk) |
1134 for chunk in f: | 1133 elif header == "HG10UN": |
1135 yield chunk | 1134 def generator(f): |
1135 for chunk in f: | |
1136 yield chunk | |
1137 else: | |
1138 req.write("0\n") | |
1139 req.write(_("unknown bundle compression type\n")) | |
1140 return | |
1141 gen = generator(util.filechunkiter(fp, 4096)) | |
1142 | |
1143 # send addchangegroup output to client | |
1144 | |
1145 old_stdout = sys.stdout | |
1146 sys.stdout = cStringIO.StringIO() | |
1147 | |
1148 try: | |
1149 url = 'remote:%s:%s' % (proto, | |
1150 req.env.get('REMOTE_HOST', '')) | |
1151 try: | |
1152 ret = self.repo.addchangegroup( | |
1153 util.chunkbuffer(gen), 'serve', url) | |
1154 except util.Abort, inst: | |
1155 sys.stdout.write("abort: %s\n" % inst) | |
1156 ret = 0 | |
1157 finally: | |
1158 val = sys.stdout.getvalue() | |
1159 sys.stdout = old_stdout | |
1160 req.write('%d\n' % ret) | |
1161 req.write(val) | |
1162 finally: | |
1163 lock.release() | |
1164 except (OSError, IOError), inst: | |
1165 req.write('0\n') | |
1166 filename = getattr(inst, 'filename', '') | |
1167 # Don't send our filesystem layout to the client | |
1168 if filename.startswith(self.repo.root): | |
1169 filename = filename[len(self.repo.root)+1:] | |
1136 else: | 1170 else: |
1137 req.write("0\n") | 1171 filename = '' |
1138 req.write(_("unknown bundle compression type\n")) | 1172 error = getattr(inst, 'strerror', 'Unknown error') |
1139 return | 1173 req.write('%s: %s\n' % (error, filename)) |
1140 gen = generator(util.filechunkiter(fp, 4096)) | |
1141 | |
1142 # send addchangegroup output to client | |
1143 | |
1144 old_stdout = sys.stdout | |
1145 sys.stdout = cStringIO.StringIO() | |
1146 | |
1147 try: | |
1148 url = 'remote:%s:%s' % (proto, | |
1149 req.env.get('REMOTE_HOST', '')) | |
1150 try: | |
1151 ret = self.repo.addchangegroup(util.chunkbuffer(gen), | |
1152 'serve', url) | |
1153 except util.Abort, inst: | |
1154 sys.stdout.write("abort: %s\n" % inst) | |
1155 ret = 0 | |
1156 finally: | |
1157 val = sys.stdout.getvalue() | |
1158 sys.stdout = old_stdout | |
1159 req.write('%d\n' % ret) | |
1160 req.write(val) | |
1161 finally: | |
1162 lock.release() | |
1163 finally: | 1174 finally: |
1164 fp.close() | 1175 fp.close() |
1165 os.unlink(tempname) | 1176 os.unlink(tempname) |
1166 | 1177 |
1167 def do_stream_out(self, req): | 1178 def do_stream_out(self, req): |