On Mon, 2014-05-19 at 18:12 +1000, Bryan Turner wrote:
> On Sat, May 17, 2014 at 9:01 AM, brian m. carlson
> <sand...@crustytoothpaste.net> wrote:
> > On Tue, May 13, 2014 at 09:39:59AM +0200, "Ákos, Tajti" wrote:
> >> Dear List,
> >> we implemented our own git smart http server to be able to check
> >> permissions
> >> and other thing before pushes. It works fine, however, the error messages
> >> we
> >> generate on the server side are not displayed by the command line client.
> >> On
> >> the server we generate error messages like this:
> >> response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
> >> response.getWriter().write(msg);
> >> On the command line we get this:
> >> Total 0 (delta 0), reused 0 (delta 0)
> >> POST git-receive-pack (290 bytes)
> >> efrror: RPC failed; result=22, HTTP code = 401
> >> atal: The remote end hung up unexpectedly
> >> fatal: The remote end hung up unexpectedly
> >> The server message is completely missing. Is there a solution for this?
> You should not need a patched git; the wire protocol itself has a
> mechanism for sending "smart" error messages. It's not particularly
> _obvious_, but it's there.
> For starters, to return an error message, your status must be 200 OK.
> You can't return any other status code or Git will interpret your
> error as some form of _HTTP_ error rather than a _git_ error.
> In the smart protocol the client sends a service to the server as a
> query parameter, like "?service=git-receive-pack". For such a request,
> you need to:
> - Set the content type to "application/x-<service>-advertisement"
> (e.g. "application/x-git-receive-pack-advertisement") (Not all command
> line Git versions require this, but JGit does)
> - Set the status code as 200 OK
> - Write back a payload where the first 4 bytes are the hex-encoded
> length of the text (where "FFFF" is max length for a single packet).
> Note that the 4 bytes for the size are _part_ of that length, so if
> you're writing "Test" the length is 8, not 4
> - After the size, you write "# service=<service>" (e.g. "#
> service=git-receive-pack"; note the space after the #) This is the
> metadata. For an error, you don't really have much to say.
> - After that, an empty packet, which is "0000" (four zeros) This
> separates the metadata from the ref advertisement
> - After that you can write your message, beginning with "ERR " (note
> the trailing space there). The "ERR " tells Git what you're writing
> isn't a ref, it's an error. I'd recommend appending a newline (and add
> 1 more to your length for it), because when Git echoes your error
> message it doesn't seem to do that
> I'm not sure whether there's a document that describes all of this; I
> found it by digging into the Git source code (you can find the "ERR"
> handling in connect.c, get_remote_heads). This may be exploiting the
> protocol, I'll leave that to someone more knowledgeable on how they
> _intended_ this all to be used, but it works for us.
> A full example looks something like this: "0036#
> service=git-receive-pack0000ERR This is a test\n"
This is indeed documented, namely in
I guess it could do with an example, but your usage seems correct. There
are two different places where things could go wrong, either in HTTP,
such as authentication, or in the Git part of the request. If you return
an HTTP 404, then all you're telling the client is that you couldn't
find what it asked for, but that could mean either the
receice-pack/upload-pack program or the repository itself. If something
went wrong at the Git level, whether it's a resource problem in the
server or simply that the repo doesn't exist, then ERR is the right
thing to use.
Particularly, we can't rely on the HTTP 404 response being anything
meaningful, as it could simply be the host's default 404 page, and you
don't want html flying through your terminal.
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html