Show More
@@ -152,7 +152,8 b' class local(object):' | |||||
152 |
|
152 | |||
153 | realoid = sha256.hexdigest() |
|
153 | realoid = sha256.hexdigest() | |
154 | if realoid != oid: |
|
154 | if realoid != oid: | |
155 |
raise |
|
155 | raise LfsCorruptionError(_('corrupt remote lfs object: %s') | |
|
156 | % oid) | |||
156 |
|
157 | |||
157 | self._linktousercache(oid) |
|
158 | self._linktousercache(oid) | |
158 |
|
159 | |||
@@ -526,8 +527,8 b' def _deduplicate(pointers):' | |||||
526 | def _verify(oid, content): |
|
527 | def _verify(oid, content): | |
527 | realoid = hashlib.sha256(content).hexdigest() |
|
528 | realoid = hashlib.sha256(content).hexdigest() | |
528 | if realoid != oid: |
|
529 | if realoid != oid: | |
529 |
raise |
|
530 | raise LfsCorruptionError(_('detected corrupt lfs object: %s') % oid, | |
530 | hint=_('run hg verify')) |
|
531 | hint=_('run hg verify')) | |
531 |
|
532 | |||
532 | def remote(repo, remote=None): |
|
533 | def remote(repo, remote=None): | |
533 | """remotestore factory. return a store in _storemap depending on config |
|
534 | """remotestore factory. return a store in _storemap depending on config | |
@@ -573,3 +574,8 b' def remote(repo, remote=None):' | |||||
573 |
|
574 | |||
574 | class LfsRemoteError(error.RevlogError): |
|
575 | class LfsRemoteError(error.RevlogError): | |
575 | pass |
|
576 | pass | |
|
577 | ||||
|
578 | class LfsCorruptionError(error.Abort): | |||
|
579 | """Raised when a corrupt blob is detected, aborting an operation | |||
|
580 | ||||
|
581 | It exists to allow specialized handling on the server side.""" |
@@ -20,6 +20,8 b' from mercurial import (' | |||||
20 | pycompat, |
|
20 | pycompat, | |
21 | ) |
|
21 | ) | |
22 |
|
22 | |||
|
23 | from . import blobstore | |||
|
24 | ||||
23 | HTTP_OK = hgwebcommon.HTTP_OK |
|
25 | HTTP_OK = hgwebcommon.HTTP_OK | |
24 | HTTP_CREATED = hgwebcommon.HTTP_CREATED |
|
26 | HTTP_CREATED = hgwebcommon.HTTP_CREATED | |
25 | HTTP_BAD_REQUEST = hgwebcommon.HTTP_BAD_REQUEST |
|
27 | HTTP_BAD_REQUEST = hgwebcommon.HTTP_BAD_REQUEST | |
@@ -276,13 +278,15 b' def _processbasictransfer(repo, req, res' | |||||
276 | # Content-Length, but what happens if a client sends less than it |
|
278 | # Content-Length, but what happens if a client sends less than it | |
277 | # says it will? |
|
279 | # says it will? | |
278 |
|
280 | |||
279 | # TODO: download() will abort if the checksum fails. It should raise |
|
281 | statusmessage = hgwebcommon.statusmessage | |
280 | # something checksum specific that can be caught here, and turned |
|
282 | try: | |
281 | # into an http code. |
|
283 | localstore.download(oid, req.bodyfh) | |
282 | localstore.download(oid, req.bodyfh) |
|
284 | res.status = statusmessage(HTTP_OK if existed else HTTP_CREATED) | |
|
285 | except blobstore.LfsCorruptionError: | |||
|
286 | _logexception(req) | |||
283 |
|
287 | |||
284 | statusmessage = hgwebcommon.statusmessage |
|
288 | # XXX: Is this the right code? | |
285 | res.status = statusmessage(HTTP_OK if existed else HTTP_CREATED) |
|
289 | res.status = statusmessage(422, b'corrupt blob') | |
286 |
|
290 | |||
287 | # There's no payload here, but this is the header that lfs-test-server |
|
291 | # There's no payload here, but this is the header that lfs-test-server | |
288 | # sends back. This eliminates some gratuitous test output conditionals. |
|
292 | # sends back. This eliminates some gratuitous test output conditionals. | |
@@ -296,9 +300,18 b' def _processbasictransfer(repo, req, res' | |||||
296 | res.status = hgwebcommon.statusmessage(HTTP_OK) |
|
300 | res.status = hgwebcommon.statusmessage(HTTP_OK) | |
297 | res.headers[b'Content-Type'] = b'application/octet-stream' |
|
301 | res.headers[b'Content-Type'] = b'application/octet-stream' | |
298 |
|
302 | |||
299 | # TODO: figure out how to send back the file in chunks, instead of |
|
303 | try: | |
300 | # reading the whole thing. |
|
304 | # TODO: figure out how to send back the file in chunks, instead of | |
301 | res.setbodybytes(localstore.read(oid)) |
|
305 | # reading the whole thing. (Also figure out how to send back | |
|
306 | # an error status if an IOError occurs after a partial write | |||
|
307 | # in that case. Here, everything is read before starting.) | |||
|
308 | res.setbodybytes(localstore.read(oid)) | |||
|
309 | except blobstore.LfsCorruptionError: | |||
|
310 | _logexception(req) | |||
|
311 | ||||
|
312 | # XXX: Is this the right code? | |||
|
313 | res.status = hgwebcommon.statusmessage(422, b'corrupt blob') | |||
|
314 | res.setbodybytes(b'') | |||
302 |
|
315 | |||
303 | return True |
|
316 | return True | |
304 | else: |
|
317 | else: |
@@ -236,7 +236,7 b' Test a bad checksum sent by the client i' | |||||
236 | $ hg -R client push http://localhost:$HGPORT1 |
|
236 | $ hg -R client push http://localhost:$HGPORT1 | |
237 | pushing to http://localhost:$HGPORT1/ |
|
237 | pushing to http://localhost:$HGPORT1/ | |
238 | searching for changes |
|
238 | searching for changes | |
239 |
abort: HTTP error: HTTP Error |
|
239 | abort: HTTP error: HTTP Error 422: corrupt blob (oid=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c, action=upload)! | |
240 | [255] |
|
240 | [255] | |
241 |
|
241 | |||
242 |
$ |
|
242 | $ echo 'test lfs file' > server/lfs3.bin | |
@@ -255,7 +255,7 b' Test a checksum failure during the proce' | |||||
255 |
|
255 | |||
256 | $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \ |
|
256 | $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \ | |
257 | > -R client update -r tip |
|
257 | > -R client update -r tip | |
258 |
abort: HTTP error: HTTP Error |
|
258 | abort: HTTP error: HTTP Error 422: corrupt blob (oid=276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d, action=download)! | |
259 | [255] |
|
259 | [255] | |
260 |
|
260 | |||
261 | $ $PYTHON $RUNTESTDIR/killdaemons.py $DAEMON_PIDS |
|
261 | $ $PYTHON $RUNTESTDIR/killdaemons.py $DAEMON_PIDS | |
@@ -279,14 +279,14 b' Test a checksum failure during the proce' | |||||
279 | $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob) |
|
279 | $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob) | |
280 | $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob) |
|
280 | $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob) | |
281 | $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob) |
|
281 | $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob) | |
282 |
$LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c HTTP/1.1" |
|
282 | $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c HTTP/1.1" 422 - (glob) | |
283 | $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob) |
|
283 | $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob) | |
284 | $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob) |
|
284 | $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob) | |
285 | $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=525251863cad618e55d483555f3d00a2ca99597e&heads=506bf3d83f78c54b89e81c6411adee19fdf02156+525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob) |
|
285 | $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=525251863cad618e55d483555f3d00a2ca99597e&heads=506bf3d83f78c54b89e81c6411adee19fdf02156+525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob) | |
286 | $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob) |
|
286 | $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob) | |
287 | $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 500 - (glob) |
|
287 | $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 500 - (glob) | |
288 | $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob) |
|
288 | $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob) | |
289 |
$LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" |
|
289 | $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 422 - (glob) | |
290 |
|
290 | |||
291 | $ grep -v ' File "' $TESTTMP/errors.log |
|
291 | $ grep -v ' File "' $TESTTMP/errors.log | |
292 | $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.git/info/lfs/objects/batch': (glob) |
|
292 | $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.git/info/lfs/objects/batch': (glob) | |
@@ -301,20 +301,13 b' Test a checksum failure during the proce' | |||||
301 | $LOCALIP - - [$ERRDATE$] HG error: raise IOError(errno.EIO, '%s: I/O error' % oid) (glob) |
|
301 | $LOCALIP - - [$ERRDATE$] HG error: raise IOError(errno.EIO, '%s: I/O error' % oid) (glob) | |
302 | $LOCALIP - - [$ERRDATE$] HG error: IOError: [Errno 5] b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c: I/O error (glob) |
|
302 | $LOCALIP - - [$ERRDATE$] HG error: IOError: [Errno 5] b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c: I/O error (glob) | |
303 | $LOCALIP - - [$ERRDATE$] HG error: (glob) |
|
303 | $LOCALIP - - [$ERRDATE$] HG error: (glob) | |
304 |
$LOCALIP - - [$ERRDATE$] Exception happened |
|
304 | $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.hg/lfs/objects/b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c': (glob) | |
305 | Traceback (most recent call last): |
|
305 | $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob) | |
306 | self.do_write() |
|
306 | $LOCALIP - - [$ERRDATE$] HG error: localstore.download(oid, req.bodyfh) (glob) | |
307 | self.do_hgweb() |
|
307 | $LOCALIP - - [$ERRDATE$] HG error: super(badstore, self).download(oid, src) (glob) | |
308 | for chunk in self.server.application(env, self._start_response): |
|
308 | $LOCALIP - - [$ERRDATE$] HG error: % oid) (glob) | |
309 | for r in self._runwsgi(req, res, repo): |
|
309 | $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: corrupt remote lfs object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c (glob) | |
310 | rctx, req, res, self.check_perm) |
|
310 | $LOCALIP - - [$ERRDATE$] HG error: (glob) | |
311 | return func(*(args + a), **kw) |
|
|||
312 | lambda perm: |
|
|||
313 | localstore.download(oid, req.bodyfh) |
|
|||
314 | super(badstore, self).download(oid, src) |
|
|||
315 | raise error.Abort(_('corrupt remote lfs object: %s') % oid) |
|
|||
316 | Abort: corrupt remote lfs object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c |
|
|||
317 |
|
||||
318 | $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob) |
|
311 | $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob) | |
319 | Traceback (most recent call last): |
|
312 | Traceback (most recent call last): | |
320 | self.do_write() |
|
313 | self.do_write() | |
@@ -329,18 +322,11 b' Test a checksum failure during the proce' | |||||
329 | raise IOError(errno.EIO, '%s: I/O error' % oid) |
|
322 | raise IOError(errno.EIO, '%s: I/O error' % oid) | |
330 | IOError: [Errno 5] 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d: I/O error |
|
323 | IOError: [Errno 5] 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d: I/O error | |
331 |
|
324 | |||
332 |
$LOCALIP - - [$ERRDATE$] Exception happened |
|
325 | $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob) | |
333 | Traceback (most recent call last): |
|
326 | $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob) | |
334 | self.do_write() |
|
327 | $LOCALIP - - [$ERRDATE$] HG error: res.setbodybytes(localstore.read(oid)) (glob) | |
335 | self.do_hgweb() |
|
328 | $LOCALIP - - [$ERRDATE$] HG error: blob = self._read(self.vfs, oid, verify) (glob) | |
336 | for chunk in self.server.application(env, self._start_response): |
|
329 | $LOCALIP - - [$ERRDATE$] HG error: blobstore._verify(oid, 'dummy content') (glob) | |
337 | for r in self._runwsgi(req, res, repo): |
|
330 | $LOCALIP - - [$ERRDATE$] HG error: hint=_('run hg verify')) (glob) | |
338 | rctx, req, res, self.check_perm) |
|
331 | $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: detected corrupt lfs object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d (glob) | |
339 | return func(*(args + a), **kw) |
|
332 | $LOCALIP - - [$ERRDATE$] HG error: (glob) | |
340 | lambda perm: |
|
|||
341 | res.setbodybytes(localstore.read(oid)) |
|
|||
342 | blob = self._read(self.vfs, oid, verify) |
|
|||
343 | blobstore._verify(oid, 'dummy content') |
|
|||
344 | hint=_('run hg verify')) |
|
|||
345 | Abort: detected corrupt lfs object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d |
|
|||
346 |
|
General Comments 0
You need to be logged in to leave comments.
Login now