{"thread":{"id":"39322","subject":"git pack protocol question: sideband responses in case of errors?","startedAt":"2015-05-13T09:03:51Z","lastAt":"2015-05-13T15:45:43Z","messageCount":2,"participants":["Christian Halstrick","Shawn Pearce"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"261144","messageId":"CAENte7j9De5Bqu2jDcmXQAxZheSGo+EntzsYUaen0N7cnuiCDQ@mail.gmail.com","threadId":"39322","inReplyTo":null,"subject":"git pack protocol question: sideband responses in case of errors?","fromName":"Christian Halstrick","fromEmail":"christian.halstrick@gmail.com","sentAt":"2015-05-13T09:03:51Z","receivedAt":"2015-05-13T09:03:51Z","isPatch":false,"sender":{"key":"christian.halstrick@gmail.com","avatar":"https://gravatar.com/avatar/3598bf518644c7dc32d4dcd8e0554b6a313e12103011862402c83ae2854203ce?d=mp&s=160"},"body":"Hi,\n\nsince a long time I am hitting very seldom errors when pushing with a\njgit client leading to \"invalid channel 101\" errors on client side. I\nwas always wondering why it was always the channel \"101\". Now I found\nout with wireshark and it leads me to a question regarding the git\npack protocol [1] and the sideband capability [2] which I couldn't\nanswer from the technical docs.\n\nThis is what happened: A client wants to push over http to a git\nserver. In the beginning they negotiated to use side-band-64k and\nreport-status capabilities. Everything works fine, Packfile data\ntransmission starts and sideband communication is ok. Now the server\nhits a severe problem persisting the packfile and wants to stop the\ntransport. The git server hit's quotas on the filesystem usage and is\nnot allowed to persist that big file. My git server (I use a modified\ngerrit server) intends to send back a packet line \"0013error: ...\".\nBut the client when reading that respond still thinks we should use\nsideband communication and interpretes the \"e\" from \"error\" as\nchannel. The ascii code of \"e\" is the solution why it was always\n\"invalid channel 101\"\n\nHere is my question:\n- When exactly should sideband communication during a http based push\nstart and when should it end? Especially in case of an error on the\nserver side. Is the server allowed to switch to non-sideband\ncommunication under special conditions? E.g. when the server responds\nnot with 200OK but with 413 (entity too large).\n- Is responding with status code 200 mandatory when talking git pack\nprotocol? Am I allowed as git server to respond with status code 413\nand fill the body of the response with the status report?\n\nCiao\n  Chris\n\n[1] https://raw.githubusercontent.com/git/git/master/Documentation/technical/pack-protocol.txt\n[2] https://raw.githubusercontent.com/git/git/master/Documentation/technical/protocol-capabilities.txt\n"},{"id":"261186","messageId":"CAJo=hJtcM-kV+L_yUX43UPe2Z-4LnaXTBpmFaWaFReG-Jbsisw@mail.gmail.com","threadId":"39322","inReplyTo":"CAENte7j9De5Bqu2jDcmXQAxZheSGo+EntzsYUaen0N7cnuiCDQ@mail.gmail.com","subject":"Re: git pack protocol question: sideband responses in case of errors?","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2015-05-13T15:45:43Z","receivedAt":"2015-05-13T15:45:43Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"On Wed, May 13, 2015 at 2:03 AM, Christian Halstrick\n<christian.halstrick@gmail.com> wrote:\n> since a long time I am hitting very seldom errors when pushing with a\n> jgit client leading to \"invalid channel 101\" errors on client side. I\n> was always wondering why it was always the channel \"101\". Now I found\n> out with wireshark and it leads me to a question regarding the git\n> pack protocol [1] and the sideband capability [2] which I couldn't\n> answer from the technical docs.\n>\n> This is what happened: A client wants to push over http to a git\n> server. In the beginning they negotiated to use side-band-64k and\n> report-status capabilities. Everything works fine, Packfile data\n> transmission starts and sideband communication is ok. Now the server\n> hits a severe problem persisting the packfile and wants to stop the\n> transport. The git server hit's quotas on the filesystem usage and is\n> not allowed to persist that big file. My git server (I use a modified\n> gerrit server) intends to send back a packet line \"0013error: ...\".\n> But the client when reading that respond still thinks we should use\n> sideband communication and interpretes the \"e\" from \"error\" as\n> channel. The ascii code of \"e\" is the solution why it was always\n> \"invalid channel 101\"\n>\n> Here is my question:\n> - When exactly should sideband communication during a http based push\n> start and when should it end?\n\nIf the client asked side-band-64k and report-status capabilities the\nserver must use side-band to respond to the client. Its (obviously)\nassuming this.\n\nThe bug here is JGit's ReceivePack/BaseReceivePack code not setting up\nthe side-band-64k early enough for this failure report to be wrapped\nin it.\n\n> Especially in case of an error on the\n> server side. Is the server allowed to switch to non-sideband\n> communication under special conditions?\n\nNo. The protocol has negotiated to use side-band-64k. That is what the\nclient expects to see.\n\nIn side-band-64k channel 2 is the \"error\" channel. Send a single\npacket on channel 2 carrying a single short text message and the\nentire stream is aborted at the client side after receiving this\nmessage. This is maybe what JGit should do in this case.\n\n> E.g. when the server responds\n> not with 200OK but with 413 (entity too large).\n\nNo, you cannot use 413.\n\n> - Is responding with status code 200 mandatory when talking git pack\n> protocol? Am I allowed as git server to respond with status code 413\n> and fill the body of the response with the status report?\n\nThis was hashed out a long time ago. For the purposes of Git the HTTP\n200 status code means the HTTP system successfully transported opaque\ndata for Git, e.g. its like having no socket error from a socket\nroutine.\n\nAny other HTTP status like 413 means the HTTP transport is busted. Its\nlike getting EHOSTUNREACH or some other such errno from a socket\nfunction.\n\nI realize there are other interpretations for how applications should\nuse HTTP status codes, and REST APIs often use them, but Git does not\ntake that approach.\n\nFWIW I am glad you found this. I have been chasing this bug for years\nbut couldn't really pin it down to anything. If its the \"pack won't\nfit on local disk due to disk full\" condition that narrows down the\noffending section of JGit considerably.\n\n\n> [1] https://raw.githubusercontent.com/git/git/master/Documentation/technical/pack-protocol.txt\n> [2] https://raw.githubusercontent.com/git/git/master/Documentation/technical/protocol-capabilities.txt\n"}]}