{"thread":{"id":"21164","subject":"[RFC PATCH 3/4] Add smart-http options to upload-pack, receive-pack","startedAt":"2009-10-09T05:22:44Z","lastAt":"2013-09-10T17:07:58Z","messageCount":46,"participants":["Shawn O. Pearce","J.H.","Sverre Rabbelier","Alex Blewitt","Jakub Narebski","Jeff King","Junio C Hamano","Antti-Juhani Kaijanaho","Tay Ray Chuan","H. Peter Anvin","Mike Hommey","Scott Chacon"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"124419","messageId":"1255065768-10428-1-git-send-email-spearce@spearce.org","threadId":"21164","inReplyTo":null,"subject":"[RFC PATCH 0/4] Return of smart HTTP","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-10-09T05:22:44Z","receivedAt":"2009-10-09T05:22:44Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"This is an RFC series to restart the smart HTTP transport work.\n\nThose familiar with the native git:// protocol should be able to\nquickly understand what I'm doing here by looking at only the last\ntwo patches.\n\nThis time around I actually have the whole thing fully implemented\nin JGit (both client and server), and am now trying to port that\nover to C git.git, as well as document it in depth.\n\nThe JGit series can be found here at Eclipse.org:\n\n  http://egit.eclipse.org/r/\n  git://egit.eclipse.org/egit/parallelip-jgit refs/changes/50/50/4\n\nThis RFC C Git series only implements the server side, and only\nhas partial documentation.  I did some limited smoke testing with\nthe JGit client against this server, it seems to work as expected.\n\nI plan on trying to write the C Git clients tomorrow.  The\nsend-pack/receive-pack protocol is trivial and shouldn't be\nthat hard, but the fetch-pack/upload-pack protocol is going\nto be somewhat interesting...\n\n\nShawn O. Pearce (4):\n  Document the HTTP transport protocol\n  Git-aware CGI to provide dumb HTTP transport\n  Add smart-http options to upload-pack, receive-pack\n  Smart fetch and push over HTTP: server side\n\n .gitignore                                |    1 +\n Documentation/technical/http-protocol.txt |  542 +++++++++++++++++++++++++++++\n Makefile                                  |    1 +\n builtin-receive-pack.c                    |   26 +-\n http-backend.c                            |  394 +++++++++++++++++++++\n upload-pack.c                             |   40 ++-\n 6 files changed, 994 insertions(+), 10 deletions(-)\n create mode 100644 Documentation/technical/http-protocol.txt\n create mode 100644 http-backend.c\n"},{"id":"124421","messageId":"1255065768-10428-2-git-send-email-spearce@spearce.org","threadId":"21164","inReplyTo":"1255065768-10428-1-git-send-email-spearce@spearce.org","subject":"[RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-10-09T05:22:45Z","receivedAt":"2009-10-09T05:22:45Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Signed-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n Documentation/technical/http-protocol.txt |  542 +++++++++++++++++++++++++++++\n 1 files changed, 542 insertions(+), 0 deletions(-)\n create mode 100644 Documentation/technical/http-protocol.txt\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nnew file mode 100644\nindex 0000000..316d9b6\n--- /dev/null\n+++ b/Documentation/technical/http-protocol.txt\n@@ -0,0 +1,542 @@\n+HTTP transfer protocols\n+=======================\n+\n+Git supports two HTTP based transfer protocols.  A \"dumb\" protocol\n+which requires only a standard HTTP server on the server end of the\n+connection, and a \"smart\" protocol which requires a Git aware CGI\n+(or server module).  This document describes both protocols.\n+\n+As a design feature smart clients can automatically upgrade \"dumb\"\n+protocol URLs to smart URLs.  This permits all users to have the\n+same published URL, and the peers automatically select the most\n+efficient transport available to them.\n+\n+\n+URL Format\n+----------\n+\n+URLs for Git repositories accessed by HTTP use the standard HTTP\n+URL syntax documented by RFC 1738, so they are of the form:\n+\n+  http://<host>:<port>/<path>\n+\n+Within this documentation the placeholder $GIT_URL will stand for\n+the http:// repository URL entered by the end-user.\n+\n+Both the \"smart\" and \"dumb\" HTTP protocols used by Git operate\n+by appending additional path components onto the end of the user\n+supplied $GIT_URL string.\n+\n+Clients MUST strip a trailing '/', if present, from the user supplied\n+$GIT_URL string to prevent empty path tokens ('//') from appearing\n+in any URL sent to a server.  Compatible clients must expand\n+'$GIT_URL/info/refs' as 'foo/info/refs' and not 'foo//info/refs'.\n+\n+\n+Authentication\n+--------------\n+\n+Standard HTTP authentication is used if authentication is required\n+to access a repository, and MAY be configured and enforced by the\n+HTTP server software.\n+\n+Because Git repositories are accessed by standard path components\n+server administrators MAY use directory based permissions within\n+their HTTP server to control repository access.\n+\n+Clients SHOULD support Basic authentication as described by RFC 2616.\n+Servers SHOULD support Basic authentication by relying upon the\n+HTTP server placed in front of the Git server software.\n+\n+Servers MUST NOT require HTTP cookies for the purposes of\n+authentication or access control.\n+\n+Clients and servers MAY support other common forms of HTTP based\n+authentication, such as Digest authentication.\n+\n+\n+SSL\n+---\n+\n+Clients and servers SHOULD support SSL, particularly to protect\n+passwords when relying on Basic HTTP authentication.\n+\n+\n+Session State\n+-------------\n+\n+The Git over HTTP protocol (much like HTTP itself) is stateless\n+from the perspective of the HTTP server side.  All state must be\n+retained and managed by the client process.  This permits simple\n+round-robin load-balancing on the server side, without needing to\n+worry about state mangement.\n+\n+Clients MUST NOT require state management on the server side in\n+order to function correctly.\n+\n+Servers MUST NOT require HTTP cookies in order to function correctly.\n+Clients MAY store and forward HTTP cookies during request processing\n+as described by RFC 2616 (HTTP/1.1).  Servers SHOULD ignore any\n+cookies sent by a client.\n+\n+\n+pkt-line Format\n+---------------\n+\n+Much (but not all) of the payload is described around pkt-lines.\n+\n+A pkt-line is a variable length binary string.  The first four bytes\n+of the line indicates the total length of the line, in hexadecimal.\n+The total length includes the 4 bytes used to denote the length.\n+A line SHOULD BE terminated by an LF, which if present MUST be\n+included in the total length.\n+\n+A pkt-line MAY contain binary data, so implementors MUST ensure all\n+pkt-line parsing/formatting routines are 8-bit clean.  The maximum\n+length of a pkt-line's data is 65532 bytes (65536 - 4).\n+\n+Examples (as C-style strings):\n+\n+  pkt-line          actual value\n+  ---------------------------------\n+  \"0006a\\n\"         \"a\\n\"\n+  \"0005a\"           \"a\"\n+  \"000bfoobar\\n\"    \"foobar\\n\"\n+  \"0004\"            \"\"\n+\n+A pkt-line with a length of 0 (\"0000\") is a special case and MUST\n+be treated as a message break or terminator in the payload.\n+\n+\n+General Request Processing\n+--------------------------\n+\n+Except where noted, all standard HTTP behavior SHOULD be assumed\n+by both client and server.  This includes (but is not necessarily\n+limited to):\n+\n+If there is no repository at $GIT_URL, the server MUST respond with\n+the '404 Not Found' HTTP status code.\n+\n+If there is a repository at $GIT_URL, but access is not currently\n+permitted, the server MUST respond with the '403 Forbidden' HTTP\n+status code.\n+\n+Servers SHOULD support both HTTP 1.0 and HTTP 1.1.\n+Servers SHOULD support chunked encoding for both\n+request and response bodies.\n+\n+Clients SHOULD support both HTTP 1.0 and HTTP 1.1.\n+Clients SHOULD support chunked encoding for both\n+request and response bodies.\n+\n+Servers MAY return ETag and/or Last-Modified headers.\n+\n+Clients MAY revalidate cached entities by including If-Modified-Since\n+and/or If-None-Match request headers.\n+\n+Servers MAY return '304 Not Modified' if the relevant headers appear\n+in the request and the entity has not changed.  Clients MUST treat\n+'304 Not Modified' identical to '200 OK' by reusing the cached entity.\n+\n+Clients MAY reuse a cached entity without revalidation if the\n+Cache-Control and/or Expires header permits caching.  Clients and\n+servers MUST follow RFC 2616 for cache controls.\n+\n+\n+Discovering References\n+----------------------\n+\n+All HTTP clients MUST begin either a fetch or a push exchange by\n+discovering the references available on the remote repository.\n+\n+Dumb Clients\n+~~~~~~~~~~~~\n+\n+HTTP clients that only support the \"dumb\" protocol MUST discover\n+references by making a request for the special info/refs file of\n+the repository.\n+\n+Dumb HTTP clients MUST NOT include search/query parameters when\n+fetching the info/refs file.  (That is, '?' must not appear in the\n+requested URL.)\n+\n+\tC: GET $GIT_URL/info/refs HTTP/1.0\n+\n+\tS: 200 OK\n+\tS:\n+\tS: 95dcfa3633004da0049d3d0fa03f80589cbcaf31\trefs/heads/maint\n+\tS: d049f6c27a2244e12041955e262a404c7faba355\trefs/heads/master\n+\tS: 2cb58b79488a98d2721cea644875a8dd0026b115\trefs/tags/v1.0\n+\tS: a3c2e2402b99163d1d59756e5f207ae21cccba4c\trefs/tags/v1.0^{}\n+\n+The Content-Type of the returned info/refs entity SHOULD be\n+\"text/plain; charset=utf-8\", but MAY be any content type.\n+Clients MUST NOT attempt to validate the returned Content-Type.\n+Dumb servers MUST NOT return a return type starting with\n+\"application/x-git-\".\n+\n+Cache-Control headers MAY be returned to disable caching of the\n+returned entity.\n+\n+When examining the response clients SHOULD only examine the HTTP\n+status code.  Valid responses are '200 OK', or '304 Not Modified'.\n+\n+The returned content is a UNIX formatted text file describing\n+each ref and its known value.  The file SHOULD be sorted by name\n+according to the C locale ordering.  The file SHOULD NOT include\n+the default ref named 'HEAD'.\n+\n+\tinfo_refs     = *( ref_record )\n+\tref_record    = any_ref | peeled_ref\n+\n+\tany_ref       = id HT name LF\n+\tpeeled_ref    = id HT name LF\n+\t                id HT name \"^{}\" LF\n+\tid            = 40*HEX\n+\n+\tHEX           = \"0\"..\"9\" | \"a\"..\"f\"\n+\tLF            = <US-ASCII LF, linefeed (10)>\n+\tHT            = <US-ASCII HT, horizontal-tab (9)>\n+\n+Smart Clients\n+~~~~~~~~~~~~~\n+\n+HTTP clients that support the \"smart\" protocol (or both the\n+\"smart\" and \"dumb\" protocols) MUST discover references by making\n+a paramterized request for the info/refs file of the repository.\n+\n+The request MUST contain exactly one query parameter,\n+'service=$servicename', where $servicename MUST be the service\n+name the client wishes to contact to complete the operation.\n+The request MUST NOT contain additional query parameters.\n+\n+\tC: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0\n+\n+\tdumb server reply:\n+\tS: 200 OK\n+\tS:\n+\tS: 95dcfa3633004da0049d3d0fa03f80589cbcaf31\trefs/heads/maint\n+\tS: d049f6c27a2244e12041955e262a404c7faba355\trefs/heads/master\n+\tS: 2cb58b79488a98d2721cea644875a8dd0026b115\trefs/tags/v1.0\n+\tS: a3c2e2402b99163d1d59756e5f207ae21cccba4c\trefs/tags/v1.0^{}\n+\n+\tsmart server reply:\n+\tS: 200 OK\n+\tS: Content-Type: application/x-git-upload-pack-advertisement\n+\tS: Cache-Control: no-cache\n+\tS:\n+\tS: ....# service=git-upload-pack\n+\tS: ....95dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint\\0 multi_ack\n+\tS: ....d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\n+\tS: ....2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0\n+\tS: ....a3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}\n+\n+Dumb Server Response\n+^^^^^^^^^^^^^^^^^^^^\n+Dumb servers MUST respond with the dumb server reply format.\n+\n+See the prior section under dumb clients for a more detailed\n+description of the dumb server response.\n+\n+Smart Server Response\n+^^^^^^^^^^^^^^^^^^^^^\n+Smart servers MUST respond with the smart server reply format.\n+\n+If the server does not recognize the requested service name, or the\n+requested service name has been disabled by the server administrator,\n+the server MUST respond with the '403 Forbidden' HTTP status code.\n+\n+Cache-Control headers SHOULD be used to disable caching of the\n+returned entity.\n+\n+The Content-Type MUST be 'application/x-$servicename-advertisement'.\n+Clients SHOULD fall back to the dumb protocol if another content\n+type is returned.  When falling back to the dumb protocol clients\n+SHOULD NOT make an additional request to $GIT_URL/info/refs, but\n+instead SHOULD use the response already in hand.  Clients MUST NOT\n+continue if they do not support the dumb protocol.\n+\n+Clients MUST validate the status code is either '200 OK' or\n+'304 Not Modified'.\n+\n+Clients MUST validate the first five bytes of the response entity\n+matches the regex \"^[0-9a-f]{4}#\".  If this test fails, clients\n+MUST NOT continue.\n+\n+Clients MUST parse the entire response as a sequence of pkt-line\n+records.\n+\n+Clients MUST verify the first pkt-line is \"# service=$servicename\".\n+Servers MUST set $servicename to be the request parameter value.\n+Servers SHOULD include an LF at the end of this line.\n+Clients MUST ignore an LF at the end of the line.\n+\n+Servers MUST terminate the response with the magic \"0000\" end\n+pkt-line marker.\n+\n+The returned response is a pkt-line stream describing each ref and\n+its known value.  The stream SHOULD be sorted by name according to\n+the C locale ordering.  The stream SHOULD include the default ref\n+named 'HEAD' as the first ref.  The stream MUST include capability\n+declarations behind a NUL on the first ref.\n+\n+\tsmart_reply    = PKT-LINE(\"# service=$servicename\" LF)\n+\t                 ref_list\n+\t                 \"0000\"\n+\tref_list       = empty_list | populated_list\n+\n+\tempty_list     = PKT-LINE(id SP \"capabilities^{}\" NUL cap_list LF)\n+\n+\tnon_empty_list = PKT-LINE(id SP name NUL cap_list LF)\n+\t                 *ref_record\n+\n+\tcap_list      = *(SP capability) SP\n+\tref_record    = any_ref | peeled_ref\n+\n+\tany_ref       = PKT-LINE(id SP name LF)\n+\tpeeled_ref    = PKT-LINE(id SP name LF)\n+\t                PKT-LINE(id SP name \"^{}\" LF\n+\tid            = 40*HEX\n+\n+\tHEX           = \"0\"..\"9\" | \"a\"..\"f\"\n+\tNL            = <US-ASCII NUL, null (0)>\n+\tLF            = <US-ASCII LF,  linefeed (10)>\n+\tSP            = <US-ASCII SP,  horizontal-tab (9)>\n+\n+\n+Smart Service git-upload-pack\n+------------------------------\n+This service reads from the remote repository.\n+\n+Clients MUST first perform ref discovery with\n+'$GIT_URL/info/refs?service=git-upload-pack'.\n+\n+\tC: POST $GIT_URL/git-upload-pack HTTP/1.0\n+\tC: Content-Type: application/x-git-upload-pack-request\n+\tC:\n+\tC: ....want 0a53e9ddeaddad63ad106860237bbf53411d11a7\n+\tC: ....have 441b40d833fdfa93eb2908e52742248faf0ee993\n+\tC: 0000\n+\n+\tS: 200 OK\n+\tS: Content-Type: application/x-git-upload-pack-result\n+\tS: Cache-Control: no-cache\n+\tS:\n+\tS: ....ACK %s, continue\n+\tS: ....NAK\n+\n+Clients MUST NOT reuse or revalidate a cached reponse.\n+Servers MUST include sufficient Cache-Control headers\n+to prevent caching of the response.\n+\n+Servers SHOULD support all capabilities defined here.\n+\n+Clients MUST send at least one 'want' command in the request body.\n+Clients MUST NOT reference an id in a 'want' command which did not\n+appear in the response obtained through ref discovery.\n+\n+\tcompute_request   = want_list\n+\t                    have_list\n+\t                    request_end\n+\trequest_end       = \"0000\" | \"done\"\n+\n+\twant_list         = PKT-LINE(want NUL cap_list LF)\n+\t                    *(want_pkt)\n+\twant_pkt          = PKT-LINE(want LF)\n+\twant              = \"want\" SP id\n+\tcap_list          = *(SP capability) SP\n+\n+\thave_list         = *PKT-LINE(\"have\" SP id LF)\n+\n+\tcommand           = create | delete | update\n+\tcreate            = 40*\"0\" SP new_id SP name\n+\tdelete            = old_id SP 40*\"0\" SP name\n+\tupdate            = old_id SP new_id SP name\n+\n+TODO: Document this further.\n+TODO: Don't use uppercase for variable names below.\n+\n+Capability include-tag\n+~~~~~~~~~~~~~~~~~~~~~~\n+\n+When packing an object that an annotated tag points at, include the\n+tag object too.  Clients can request this if they want to fetch\n+tags, but don't know which tags they will need until after they\n+receive the branch data.  By enabling include-tag an entire call\n+to upload-pack can be avoided.\n+\n+Capability thin-pack\n+~~~~~~~~~~~~~~~~~~~~\n+\n+When packing a deltified object the base is not included if the base\n+is reachable from an object listed in the COMMON set by the client.\n+This reduces the bandwidth required to transfer, but it does slightly\n+increase processing time for the client to save the pack to disk.\n+\n+The Negotiation Algorithm\n+~~~~~~~~~~~~~~~~~~~~~~~~~\n+The computation to select the minimal pack proceeds as follows\n+(c = client, s = server):\n+\n+ init step:\n+ (c) Use ref discovery to obtain the advertised refs.\n+ (c) Place any object seen into set ADVERTISED.\n+\n+ (c) Build an empty set, COMMON, to hold the objects that are later\n+     determined to be on both ends.\n+ (c) Build a set, WANT, of the objects from ADVERTISED the client\n+     wants to fetch, based on what it saw during ref discovery.\n+\n+ (c) Start a queue, C_PENDING, ordered by commit time (popping newest\n+     first).  Add all client refs.  When a commit is popped from\n+     the queue its parents should be automatically inserted back.\n+     Commits MUST only enter the queue once.\n+\n+ one compute step:\n+ (c) Send one $GIT_URL/git-upload-pack request:\n+\n+\tC: 0032want <WANT #1>...............................\n+\tC: 0032want <WANT #2>...............................\n+\t....\n+\tC: 0032have <COMMON #1>.............................\n+\tC: 0032have <COMMON #2>.............................\n+\t....\n+\tC: 0032have <HAVE #1>...............................\n+\tC: 0032have <HAVE #2>...............................\n+\t....\n+\tC: 0000\n+\n+     The stream is organized into \"commands\", with each command\n+     appearing by itself in a pkt-line.  Within a command line\n+     the text leading up to the first space is the command name,\n+     and the remainder of the line to the first LF is the value.\n+     Command lines are terminated with an LF as the last byte of\n+     the pkt-line value.\n+\n+     Commands MUST appear in the following order, if they appear\n+     at all in the request stream:\n+\n+       * want\n+       * have\n+\n+     The stream is terminated by a pkt-line flush (\"0000\").\n+\n+     A single \"want\" or \"have\" command MUST have one hex formatted\n+     SHA-1 as its value.  Multiple SHA-1s MUST be sent by sending\n+     multiple commands.\n+\n+     The HAVE list is created by popping the first 32 commits\n+     from C_PENDING.  Less can be supplied if C_PENDING empties.\n+\n+     If the client has sent 256 HAVE commits and has not yet\n+     received one of those back from S_COMMON, or the client has\n+     emptied C_PENDING it should include a \"done\" command to let\n+     the server know it won't proceed:\n+\n+\tC: 0009done\n+\n+  (s) Parse the git-upload-pack request:\n+\n+      Verify all objects in WANT are directly reachable from refs.\n+\n+\t  The server MAY walk backwards through history or through\n+      the reflog to permit slightly stale requests.\n+\n+      If no WANT objects are received, send an error:\n+\n+TODO: Define error if no want lines are requested.\n+\n+      If any WANT object is not reachable, send an error:\n+\n+TODO: Define error if an invalid want is requested.\n+\n+     Create an empty list, S_COMMON.\n+\n+     If 'have' was sent:\n+\n+     Loop through the objects in the order supplied by the client.\n+     For each object, if the server has the object reachable from\n+     a ref, add it to S_COMMON.  If a commit is added to S_COMMON,\n+     do not add any ancestors, even if they also appear in HAVE.\n+\n+  (s) Send the git-upload-pack response:\n+\n+     If the server has found a closed set of objects to pack or the\n+     request ends with \"done\", it replies with the pack.\n+\n+TODO: Document the pack based response\n+\tS: PACK...\n+\n+     The returned stream is the side-band-64k protocol supported\n+     by the git-upload-pack service, and the pack is embedded into\n+     stream 1.  Progress messages from the server side may appear\n+     in stream 2.\n+\n+     Here a \"closed set of objects\" is defined to have at least\n+     one path from every WANT to at least one COMMON object.\n+\n+     If the server needs more information, it replies with a\n+     status continue response:\n+\n+TODO: Document the non-pack response\n+\n+  (c) Parse the upload-pack response:\n+\n+TODO: Document parsing response\n+\n+      Do another compute step.\n+\n+\n+Smart Service git-receive-pack\n+------------------------------\n+This service modifies the remote repository.\n+\n+Clients MUST first perform ref discovery with\n+'$GIT_URL/info/refs?service=git-receive-pack'.\n+\n+\tC: POST $GIT_URL/git-receive-pack HTTP/1.0\n+\tC: Content-Type: application/x-git-receive-pack-request\n+\tC:\n+\tC: ....0a53e9ddeaddad63ad106860237bbf53411d11a7 441b40d833fdfa93eb2908e52742248faf0ee993 refs/heads/maint\\0 report-status\n+\tC: 0000\n+\tC: PACK....\n+\n+\tS: 200 OK\n+\tS: Content-Type: application/x-git-receive-pack-result\n+\tS: Cache-Control: no-cache\n+\tS:\n+\tS: ....\n+\n+Clients MUST NOT reuse or revalidate a cached reponse.\n+Servers MUST include sufficient Cache-Control headers\n+to prevent caching of the response.\n+\n+Servers SHOULD support all capabilities defined here.\n+\n+Clients MUST send at least one command in the request body.\n+Within the command portion of the request body clients SHOULD send\n+the id obtained through ref discovery as old_id.\n+\n+\tupdate_request    = command_list\n+\t                    \"PACK\" <binary data>\n+\n+\tcommand_list      = PKT-LINE(command NUL cap_list LF)\n+\t                    *(command_pkt)\n+\tcommand_pkt       = PKT-LINE(command LF)\n+\tcap_list          = *(SP capability) SP\n+\n+\tcommand           = create | delete | update\n+\tcreate            = 40*\"0\" SP new_id SP name\n+\tdelete            = old_id SP 40*\"0\" SP name\n+\tupdate            = old_id SP new_id SP name\n+\n+TODO: Document this further.\n+\n+\n+References\n+----------\n+\n+link:http://www.ietf.org/rfc/rfc1738.txt[RFC 1738: Uniform Resource Locators (URL)]\n+link:http://www.ietf.org/rfc/rfc2616.txt[RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1]\n+\n-- \n1.6.5.rc3.193.gdf7a\n"},{"id":"124420","messageId":"1255065768-10428-3-git-send-email-spearce@spearce.org","threadId":"21164","inReplyTo":"1255065768-10428-2-git-send-email-spearce@spearce.org","subject":"[RFC PATCH 2/4] Git-aware CGI to provide dumb HTTP transport","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-10-09T05:22:46Z","receivedAt":"2009-10-09T05:22:46Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"The git-http-backend CGI can be configured into any Apache server\nusing ScriptAlias, such as with the following configuration:\n\n  LoadModule cgi_module /usr/libexec/apache2/mod_cgi.so\n  LoadModule alias_module /usr/libexec/apache2/mod_alias.so\n  ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/\n\nRepositories are accessed via the translated PATH_INFO.\n\nThe CGI is backwards compatible with the dumb client, allowing all\nolder HTTP clients to continue to download repositories which are\nmanaged by the CGI.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n .gitignore     |    1 +\n Makefile       |    1 +\n http-backend.c |  261 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 263 insertions(+), 0 deletions(-)\n create mode 100644 http-backend.c\n\ndiff --git a/.gitignore b/.gitignore\nindex 51a37b1..353d22f 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -55,6 +55,7 @@ git-get-tar-commit-id\n git-grep\n git-hash-object\n git-help\n+git-http-backend\n git-http-fetch\n git-http-push\n git-imap-send\ndiff --git a/Makefile b/Makefile\nindex dd3d520..c80fb56 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -361,6 +361,7 @@ PROGRAMS += git-show-index$X\n PROGRAMS += git-unpack-file$X\n PROGRAMS += git-upload-pack$X\n PROGRAMS += git-var$X\n+PROGRAMS += git-http-backend$X\n \n # List built-in command $C whose implementation cmd_$C() is not in\n # builtin-$C.o but is linked in as part of some other command.\ndiff --git a/http-backend.c b/http-backend.c\nnew file mode 100644\nindex 0000000..39cfd25\n--- /dev/null\n+++ b/http-backend.c\n@@ -0,0 +1,261 @@\n+#include \"cache.h\"\n+#include \"refs.h\"\n+#include \"pkt-line.h\"\n+#include \"object.h\"\n+#include \"tag.h\"\n+#include \"exec_cmd.h\"\n+#include \"run-command.h\"\n+\n+static const char content_type[] = \"Content-Type\";\n+static const char content_length[] = \"Content-Length\";\n+\n+static char buffer[1024];\n+\n+static const char *http_date(unsigned long time)\n+{\n+\treturn show_date(time, 0, DATE_RFC2822);\n+}\n+\n+static void format_write(const char *fmt, ...)\n+{\n+\tva_list args;\n+\tunsigned n;\n+\n+\tva_start(args, fmt);\n+\tn = vsnprintf(buffer, sizeof(buffer), fmt, args);\n+\tva_end(args);\n+\tif (n >= sizeof(buffer))\n+\t\tdie(\"protocol error: impossibly long line\");\n+\n+\tsafe_write(1, buffer, n);\n+}\n+\n+static void write_status(unsigned code, const char *msg)\n+{\n+\tformat_write(\"Status: %u %s\\r\\n\", code, msg);\n+}\n+\n+static void write_header(const char *name, const char *value)\n+{\n+\tformat_write(\"%s: %s\\r\\n\", name, value);\n+}\n+\n+static void end_headers(void)\n+{\n+\tsafe_write(1, \"\\r\\n\", 2);\n+}\n+\n+static void write_nocache(void)\n+{\n+\twrite_header(\"Expires\", \"Fri, 01 Jan 1980 00:00:00 GMT\");\n+\twrite_header(\"Pragma\", \"no-cache\");\n+\twrite_header(\"Cache-Control\", \"no-cache, max-age=0, must-revalidate\");\n+}\n+\n+static void write_cache_forever(void)\n+{\n+\tunsigned long now = time(NULL);\n+\twrite_header(\"Date\", http_date(now));\n+\twrite_header(\"Expires\", http_date(now + 31536000));\n+\twrite_header(\"Cache-Control\", \"public, max-age=31536000\");\n+}\n+\n+static NORETURN void not_found(const char *err, ...)\n+{\n+\tva_list params;\n+\n+\twrite_status(404, \"Not Found\");\n+\twrite_nocache();\n+\tend_headers();\n+\n+\tva_start(params, err);\n+\tif (err && *err) {\n+\t\tvsnprintf(buffer, sizeof(buffer), err, params);\n+\t\tfprintf(stderr, \"%s\\n\", buffer);\n+\t}\n+\tva_end(params);\n+\texit(0);\n+}\n+\n+static void write_file(const char *the_type, const char *name)\n+{\n+\tconst char *p = git_path(\"%s\", name);\n+\tint fd;\n+\tstruct stat sb;\n+\tuintmax_t remaining;\n+\n+\tfd = open(p, O_RDONLY);\n+\tif (fd < 0)\n+\t\tnot_found(\"Cannot open '%s': %s\", p, strerror(errno));\n+\tif (fstat(fd, &sb) < 0)\n+\t\tdie_errno(\"Cannot stat '%s'\", p);\n+\tremaining = (uintmax_t)sb.st_size;\n+\n+\twrite_header(content_type, the_type);\n+\twrite_header(\"Last-Modified\", http_date(sb.st_mtime));\n+\tformat_write(\"Content-Length: %\" PRIuMAX \"\\r\\n\", remaining);\n+\tend_headers();\n+\n+\twhile (remaining) {\n+\t\tssize_t n = xread(fd, buffer, sizeof(buffer));\n+\t\tif (n < 0)\n+\t\t\tdie_errno(\"Cannot read '%s'\", p);\n+\t\tn = safe_write(1, buffer, n);\n+\t\tif (n <= 0)\n+\t\t\tbreak;\n+\t}\n+\tclose(fd);\n+}\n+\n+static void get_text_file(char *name)\n+{\n+\twrite_nocache();\n+\twrite_file(\"text/plain; charset=utf-8\", name);\n+}\n+\n+static void get_loose_object(char *name)\n+{\n+\twrite_cache_forever();\n+\twrite_file(\"application/x-git-loose-object\", name);\n+}\n+\n+static void get_pack_file(char *name)\n+{\n+\twrite_cache_forever();\n+\twrite_file(\"application/x-git-packed-objects\", name);\n+}\n+\n+static void get_idx_file(char *name)\n+{\n+\twrite_cache_forever();\n+\twrite_file(\"application/x-git-packed-objects-toc\", name);\n+}\n+\n+static int show_text_ref(const char *name, const unsigned char *sha1,\n+\tint flag, void *cb_data)\n+{\n+\tstruct object *o = parse_object(sha1);\n+\tif (!o)\n+\t\treturn 0;\n+\n+\tformat_write(\"%s\\t%s\\n\", sha1_to_hex(sha1), name);\n+\tif (o->type == OBJ_TAG) {\n+\t\to = deref_tag(o, name, 0);\n+\t\tif (!o)\n+\t\t\treturn 0;\n+\t\tformat_write(\"%s\\t%s^{}\\n\", sha1_to_hex(o->sha1), name);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static void get_info_refs(char *arg)\n+{\n+\twrite_nocache();\n+\twrite_header(content_type, \"text/plain; charset=utf-8\");\n+\tend_headers();\n+\n+\tfor_each_ref(show_text_ref, NULL);\n+}\n+\n+static void get_info_packs(char *arg)\n+{\n+\tsize_t objdirlen = strlen(get_object_directory());\n+\tstruct packed_git *p;\n+\n+\twrite_nocache();\n+\twrite_header(content_type, \"text/plain; charset=utf-8\");\n+\tend_headers();\n+\n+\tprepare_packed_git();\n+\tfor (p = packed_git; p; p = p->next) {\n+\t\tif (!p->pack_local)\n+\t\t\tcontinue;\n+\t\tformat_write(\"P %s\\n\", p->pack_name + objdirlen + 6);\n+\t}\n+\tsafe_write(1, \"\\n\", 1);\n+}\n+\n+static NORETURN void die_webcgi(const char *err, va_list params)\n+{\n+\twrite_status(500, \"Internal Server Error\");\n+\twrite_nocache();\n+\tend_headers();\n+\n+\tvsnprintf(buffer, sizeof(buffer), err, params);\n+\tfprintf(stderr, \"fatal: %s\\n\", buffer);\n+\texit(0);\n+}\n+\n+static struct service_cmd {\n+\tconst char *method;\n+\tconst char *pattern;\n+\tvoid (*imp)(char *);\n+} services[] = {\n+\t{\"GET\", \"/HEAD$\", get_text_file},\n+\t{\"GET\", \"/info/refs$\", get_info_refs},\n+\t{\"GET\", \"/objects/info/packs$\", get_info_packs},\n+\t{\"GET\", \"/objects/info/[^/]*$\", get_text_file},\n+\t{\"GET\", \"/objects/[0-9a-f]{2}/[0-9a-f]{38}$\", get_loose_object},\n+\t{\"GET\", \"/objects/pack/pack-[0-9a-f]{40}\\\\.pack$\", get_pack_file},\n+\t{\"GET\", \"/objects/pack/pack-[0-9a-f]{40}\\\\.idx$\", get_idx_file}\n+};\n+\n+int main(int argc, char **argv)\n+{\n+\tchar *dir = getenv(\"PATH_TRANSLATED\");\n+\tchar *input_method = getenv(\"REQUEST_METHOD\");\n+\tstruct service_cmd *cmd = NULL;\n+\tchar *cmd_arg = NULL;\n+\tint i;\n+\n+\tset_die_routine(die_webcgi);\n+\n+\tif (!dir)\n+\t\tdie(\"No PATH_TRANSLATED from server\");\n+\tif (!input_method)\n+\t\tdie(\"No REQUEST_METHOD from server\");\n+\tif (!strcmp(input_method, \"HEAD\"))\n+\t\tinput_method = \"GET\";\n+\n+\tfor (i = 0; i < ARRAY_SIZE(services); i++) {\n+\t\tstruct service_cmd *c = &services[i];\n+\t\tregex_t re;\n+\t\tregmatch_t out[1];\n+\n+\t\tif (regcomp(&re, c->pattern, REG_EXTENDED))\n+\t\t\tdie(\"Bogus regex in service table: %s\", c->pattern);\n+\t\tif (!regexec(&re, dir, 1, out, 0)) {\n+\t\t\tsize_t n = out[0].rm_eo - out[0].rm_so;\n+\n+\t\t\tif (strcmp(input_method, c->method)) {\n+\t\t\t\tconst char *proto = getenv(\"SERVER_PROTOCOL\");\n+\t\t\t\tif (proto && !strcmp(proto, \"HTTP/1.1\"))\n+\t\t\t\t\twrite_status(405, \"Method Not Allowed\");\n+\t\t\t\telse\n+\t\t\t\t\twrite_status(400, \"Bad Request\");\n+\t\t\t\twrite_nocache();\n+\t\t\t\tend_headers();\n+\t\t\t\treturn 0;\n+\t\t\t}\n+\n+\t\t\tcmd = c;\n+\t\t\tcmd_arg = xmalloc(n);\n+\t\t\tstrncpy(cmd_arg, dir + out[0].rm_so + 1, n);\n+\t\t\tcmd_arg[n] = '\\0';\n+\t\t\tdir[out[0].rm_so] = 0;\n+\t\t\tbreak;\n+\t\t}\n+\t\tregfree(&re);\n+\t}\n+\n+\tif (!cmd)\n+\t\tnot_found(\"Request not supported: '%s'\", dir);\n+\n+\tsetup_path();\n+\tif (!enter_repo(dir, 0))\n+\t\tnot_found(\"Not a git repository: '%s'\", dir);\n+\n+\tcmd->imp(cmd_arg);\n+\treturn 0;\n+}\n-- \n1.6.5.rc3.193.gdf7a\n"},{"id":"124417","messageId":"1255065768-10428-4-git-send-email-spearce@spearce.org","threadId":"21164","inReplyTo":"1255065768-10428-3-git-send-email-spearce@spearce.org","subject":"[RFC PATCH 3/4] Add smart-http options to upload-pack, receive-pack","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-10-09T05:22:47Z","receivedAt":"2009-10-09T05:22:47Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"When --smart-http is passed as a command line parameter to\nupload-pack or receive-pack the programs now assume they may\nperform only a single read-write cycle with stdin and stdout.\nThis fits with the HTTP POST request processing model where a\nprogram may read the request, write a response, and must exit.\n\nWhen --advertise-refs is passed as a command line parameter only\nthe initial ref advertisement is output, and the program exits\nimmediately.  This fits with the HTTP GET request model, where\nno request content is received but a response must be produced.\n\nHTTP headers and/or environment are not processed here, but\ninstead are assumed to be handled by the program invoking\neither service backend.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n builtin-receive-pack.c |   26 ++++++++++++++++++++------\n upload-pack.c          |   40 ++++++++++++++++++++++++++++++++++++----\n 2 files changed, 56 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin-receive-pack.c b/builtin-receive-pack.c\nindex b771fe9..a075785 100644\n--- a/builtin-receive-pack.c\n+++ b/builtin-receive-pack.c\n@@ -615,6 +615,8 @@ static void add_alternate_refs(void)\n \n int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n {\n+\tint advertise_refs = 0;\n+\tint smart_http = 0;\n \tint i;\n \tchar *dir = NULL;\n \n@@ -623,7 +625,15 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \t\tconst char *arg = *argv++;\n \n \t\tif (*arg == '-') {\n-\t\t\t/* Do flag handling here */\n+\t\t\tif (!strcmp(arg, \"--advertise-refs\")) {\n+\t\t\t\tadvertise_refs = 1;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\t\t\tif (!strcmp(arg, \"--smart-http\")) {\n+\t\t\t\tsmart_http = 1;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n \t\t\tusage(receive_pack_usage);\n \t\t}\n \t\tif (dir)\n@@ -652,12 +662,16 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \t\t\" report-status delete-refs ofs-delta \" :\n \t\t\" report-status delete-refs \";\n \n-\tadd_alternate_refs();\n-\twrite_head_info();\n-\tclear_extra_refs();\n+\tif (advertise_refs || !smart_http) {\n+\t\tadd_alternate_refs();\n+\t\twrite_head_info();\n+\t\tclear_extra_refs();\n \n-\t/* EOF */\n-\tpacket_flush(1);\n+\t\t/* EOF */\n+\t\tpacket_flush(1);\n+\t}\n+\tif (advertise_refs)\n+\t\treturn 0;\n \n \tread_head_info();\n \tif (commands) {\ndiff --git a/upload-pack.c b/upload-pack.c\nindex 38ddac2..ae67039 100644\n--- a/upload-pack.c\n+++ b/upload-pack.c\n@@ -39,6 +39,8 @@ static unsigned int timeout;\n  */\n static int use_sideband;\n static int debug_fd;\n+static int advertise_refs;\n+static int smart_http;\n \n static void reset_timeout(void)\n {\n@@ -509,6 +511,8 @@ static int get_common_commits(void)\n \t\tif (!len) {\n \t\t\tif (have_obj.nr == 0 || multi_ack)\n \t\t\t\tpacket_write(1, \"NAK\\n\");\n+\t\t\tif (smart_http)\n+\t\t\t\texit(0);\n \t\t\tcontinue;\n \t\t}\n \t\tstrip(line, len);\n@@ -705,12 +709,32 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo\n \treturn 0;\n }\n \n+static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)\n+{\n+\tstruct object *o = parse_object(sha1);\n+\tif (!o)\n+\t\tdie(\"git upload-pack: cannot find object %s:\", sha1_to_hex(sha1));\n+\tif (!(o->flags & OUR_REF)) {\n+\t\to->flags |= OUR_REF;\n+\t\tnr_our_refs++;\n+\t}\n+\treturn 0;\n+}\n+\n static void upload_pack(void)\n {\n-\treset_timeout();\n-\thead_ref(send_ref, NULL);\n-\tfor_each_ref(send_ref, NULL);\n-\tpacket_flush(1);\n+\tif (advertise_refs || !smart_http) {\n+\t\treset_timeout();\n+\t\thead_ref(send_ref, NULL);\n+\t\tfor_each_ref(send_ref, NULL);\n+\t\tpacket_flush(1);\n+\t} else {\n+\t\thead_ref(mark_our_ref, NULL);\n+\t\tfor_each_ref(mark_our_ref, NULL);\n+\t}\n+\tif (advertise_refs)\n+\t\treturn;\n+\n \treceive_needs();\n \tif (want_obj.nr) {\n \t\tget_common_commits();\n@@ -732,6 +756,14 @@ int main(int argc, char **argv)\n \n \t\tif (arg[0] != '-')\n \t\t\tbreak;\n+\t\tif (!strcmp(arg, \"--advertise-refs\")) {\n+\t\t\tadvertise_refs = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"--smart-http\")) {\n+\t\t\tsmart_http = 1;\n+\t\t\tcontinue;\n+\t\t}\n \t\tif (!strcmp(arg, \"--strict\")) {\n \t\t\tstrict = 1;\n \t\t\tcontinue;\n-- \n1.6.5.rc3.193.gdf7a\n"},{"id":"124418","messageId":"1255065768-10428-5-git-send-email-spearce@spearce.org","threadId":"21164","inReplyTo":"1255065768-10428-4-git-send-email-spearce@spearce.org","subject":"[RFC PATCH 4/4] Smart fetch and push over HTTP: server side","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-10-09T05:22:48Z","receivedAt":"2009-10-09T05:22:48Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Requests for $GIT_URL/git-receive-pack and $GIT_URL/git-upload-pack\nare forwarded to the corresponding backend process by directly\nexecuting it and leaving stdin and stdout connected to the web\nserver.  Prior to starting the backend HTTP headers are sent, thereby\nfreeing the backend from needing to know about the HTTP protocol.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n http-backend.c |  135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-\n 1 files changed, 134 insertions(+), 1 deletions(-)\n\ndiff --git a/http-backend.c b/http-backend.c\nindex 39cfd25..978f820 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -77,6 +77,95 @@ static NORETURN void not_found(const char *err, ...)\n \texit(0);\n }\n \n+static NORETURN void forbidden(const char *err, ...)\n+{\n+\tva_list params;\n+\n+\twrite_status(403, \"Forbidden\");\n+\twrite_nocache();\n+\tend_headers();\n+\n+\tva_start(params, err);\n+\tif (err && *err) {\n+\t\tvsnprintf(buffer, sizeof(buffer), err, params);\n+\t\tfprintf(stderr, \"%s\\n\", buffer);\n+\t}\n+\tva_end(params);\n+\texit(0);\n+}\n+\n+struct http_service {\n+\tconst char *name;\n+\tconst char *config_name;\n+\tint enabled;\n+};\n+static struct http_service *service;\n+\n+static struct http_service http_service[] = {\n+\t{ \"upload-pack\", \"uploadpack\", 1 },\n+\t{ \"receive-pack\", \"receivepack\", 0 },\n+};\n+\n+static int http_config(const char *var, const char *value, void *cb)\n+{\n+\tif (!prefixcmp(var, \"http.\") &&\n+\t    !strcmp(var + 7, service->config_name)) {\n+\t\tservice->enabled = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n+\n+\t/* we are not interested in parsing any other configuration here */\n+\treturn 0;\n+}\n+\n+static void select_service(const char *name)\n+{\n+\tint i;\n+\n+\tif (prefixcmp(name, \"git-\"))\n+\t\tforbidden(\"Unsupported service: '%s'\", name);\n+\n+\tfor (i = 0; i < ARRAY_SIZE(http_service); i++) {\n+\t\tservice = &http_service[i];\n+\t\tif (!strcmp(service->name, name + 4)) {\n+\t\t\tgit_config(http_config, NULL);\n+\t\t\tif (!service->enabled)\n+\t\t\t\tforbidden(\"Service not enabled: '%s'\", name);\n+\t\t\treturn;\n+\t\t}\n+\t}\n+\tforbidden(\"Unsupported service: '%s'\", name);\n+}\n+\n+static void run_service(const char **argv)\n+{\n+#ifndef WIN32\n+\texecv_git_cmd(argv);\n+#else\n+\tstruct child_process cld;\n+\n+\tmemset(&cld, 0, sizeof(cld));\n+\tcld.argv = argv;\n+\tcld.git_cmd = 1;\n+\tif (start_command(&cld))\n+\t\tdie(\"Cannot start git-%s service\", service->name);\n+\tclose(0);\n+\tclose(1);\n+\tfinish_command(&cld);\n+#endif\n+}\n+\n+static void require_content_type(const char *need_type)\n+{\n+\tconst char *input_type = getenv(\"CONTENT_TYPE\");\n+\tif (!input_type || strcmp(input_type, need_type)) {\n+\t\twrite_status(415, \"Unsupported Media Type\");\n+\t\twrite_nocache();\n+\t\tend_headers();\n+\t\texit(0);\n+\t}\n+}\n+\n static void write_file(const char *the_type, const char *name)\n {\n \tconst char *p = git_path(\"%s\", name);\n@@ -151,6 +240,25 @@ static int show_text_ref(const char *name, const unsigned char *sha1,\n \n static void get_info_refs(char *arg)\n {\n+\tchar *query = getenv(\"QUERY_STRING\");\n+\n+\tif (query && !prefixcmp(query, \"service=\")) {\n+\t\tconst char *argv[] = {NULL /* service name */,\n+\t\t\t\"--smart-http\", \"--advertise-refs\",\n+\t\t\t\".\", NULL};\n+\n+\t\tselect_service(query + 8);\n+\n+\t\twrite_nocache();\n+\t\tformat_write(\"%s: application/x-git-%s-advertisement\\r\\n\",\n+\t\t\tcontent_type, service->name);\n+\t\tend_headers();\n+\t\tpacket_write(1, \"# service=git-%s\\n\", service->name);\n+\n+\t\targv[0] = service->name;\n+\t\trun_service(argv);\n+\t}\n+\n \twrite_nocache();\n \twrite_header(content_type, \"text/plain; charset=utf-8\");\n \tend_headers();\n@@ -176,6 +284,28 @@ static void get_info_packs(char *arg)\n \tsafe_write(1, \"\\n\", 1);\n }\n \n+static void post_to_service(char *service_name)\n+{\n+\tconst char *argv[] = {NULL, \"--smart-http\", \".\", NULL};\n+\tunsigned n;\n+\n+\tselect_service(service_name);\n+\n+\tn = snprintf(buffer, sizeof(buffer),\n+\t\t\"application/x-git-%s-request\", service->name);\n+\tif (n >= sizeof(buffer))\n+\t\tdie(\"impossibly long service name\");\n+\trequire_content_type(buffer);\n+\n+\twrite_nocache();\n+\tformat_write(\"%s: application/x-git-%s-result\\r\\n\",\n+\t\tcontent_type, service->name);\n+\tend_headers();\n+\n+\targv[0] = service->name;\n+\trun_service(argv);\n+}\n+\n static NORETURN void die_webcgi(const char *err, va_list params)\n {\n \twrite_status(500, \"Internal Server Error\");\n@@ -198,7 +328,10 @@ static struct service_cmd {\n \t{\"GET\", \"/objects/info/[^/]*$\", get_text_file},\n \t{\"GET\", \"/objects/[0-9a-f]{2}/[0-9a-f]{38}$\", get_loose_object},\n \t{\"GET\", \"/objects/pack/pack-[0-9a-f]{40}\\\\.pack$\", get_pack_file},\n-\t{\"GET\", \"/objects/pack/pack-[0-9a-f]{40}\\\\.idx$\", get_idx_file}\n+\t{\"GET\", \"/objects/pack/pack-[0-9a-f]{40}\\\\.idx$\", get_idx_file},\n+\n+\t{\"POST\", \"/git-upload-pack$\", post_to_service},\n+\t{\"POST\", \"/git-receive-pack$\", post_to_service}\n };\n \n int main(int argc, char **argv)\n-- \n1.6.5.rc3.193.gdf7a\n"},{"id":"124422","messageId":"4ACECFAA.9090109@kernel.org","threadId":"21164","inReplyTo":"1255065768-10428-3-git-send-email-spearce@spearce.org","subject":"Re: [RFC PATCH 2/4] Git-aware CGI to provide dumb HTTP transport","fromName":"J.H.","fromEmail":"warthog9@kernel.org","sentAt":"2009-10-09T05:52:42Z","receivedAt":"2009-10-09T05:52:42Z","isPatch":true,"sender":{"key":"warthog9@kernel.org","avatar":"https://avatars.githubusercontent.com/u/2334704?v=4"},"body":"I dunno I kinda object to it being called http-backend, personally I'd \nrather it be called git-smart since this is the smart http protocol ;-)\n\n- John 'Warthog9' Hawley\n\nShawn O. Pearce wrote:\n> The git-http-backend CGI can be configured into any Apache server\n> using ScriptAlias, such as with the following configuration:\n> \n>   LoadModule cgi_module /usr/libexec/apache2/mod_cgi.so\n>   LoadModule alias_module /usr/libexec/apache2/mod_alias.so\n>   ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/\n> \n> Repositories are accessed via the translated PATH_INFO.\n> \n> The CGI is backwards compatible with the dumb client, allowing all\n> older HTTP clients to continue to download repositories which are\n> managed by the CGI.\n> \n> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>\n> ---\n>  .gitignore     |    1 +\n>  Makefile       |    1 +\n>  http-backend.c |  261 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n>  3 files changed, 263 insertions(+), 0 deletions(-)\n>  create mode 100644 http-backend.c\n> \n> diff --git a/.gitignore b/.gitignore\n> index 51a37b1..353d22f 100644\n> --- a/.gitignore\n> +++ b/.gitignore\n> @@ -55,6 +55,7 @@ git-get-tar-commit-id\n>  git-grep\n>  git-hash-object\n>  git-help\n> +git-http-backend\n>  git-http-fetch\n>  git-http-push\n>  git-imap-send\n> diff --git a/Makefile b/Makefile\n> index dd3d520..c80fb56 100644\n> --- a/Makefile\n> +++ b/Makefile\n> @@ -361,6 +361,7 @@ PROGRAMS += git-show-index$X\n>  PROGRAMS += git-unpack-file$X\n>  PROGRAMS += git-upload-pack$X\n>  PROGRAMS += git-var$X\n> +PROGRAMS += git-http-backend$X\n>  \n>  # List built-in command $C whose implementation cmd_$C() is not in\n>  # builtin-$C.o but is linked in as part of some other command.\n> diff --git a/http-backend.c b/http-backend.c\n> new file mode 100644\n> index 0000000..39cfd25\n> --- /dev/null\n> +++ b/http-backend.c\n> @@ -0,0 +1,261 @@\n> +#include \"cache.h\"\n> +#include \"refs.h\"\n> +#include \"pkt-line.h\"\n> +#include \"object.h\"\n> +#include \"tag.h\"\n> +#include \"exec_cmd.h\"\n> +#include \"run-command.h\"\n> +\n> +static const char content_type[] = \"Content-Type\";\n> +static const char content_length[] = \"Content-Length\";\n> +\n> +static char buffer[1024];\n> +\n> +static const char *http_date(unsigned long time)\n> +{\n> +\treturn show_date(time, 0, DATE_RFC2822);\n> +}\n> +\n> +static void format_write(const char *fmt, ...)\n> +{\n> +\tva_list args;\n> +\tunsigned n;\n> +\n> +\tva_start(args, fmt);\n> +\tn = vsnprintf(buffer, sizeof(buffer), fmt, args);\n> +\tva_end(args);\n> +\tif (n >= sizeof(buffer))\n> +\t\tdie(\"protocol error: impossibly long line\");\n> +\n> +\tsafe_write(1, buffer, n);\n> +}\n> +\n> +static void write_status(unsigned code, const char *msg)\n> +{\n> +\tformat_write(\"Status: %u %s\\r\\n\", code, msg);\n> +}\n> +\n> +static void write_header(const char *name, const char *value)\n> +{\n> +\tformat_write(\"%s: %s\\r\\n\", name, value);\n> +}\n> +\n> +static void end_headers(void)\n> +{\n> +\tsafe_write(1, \"\\r\\n\", 2);\n> +}\n> +\n> +static void write_nocache(void)\n> +{\n> +\twrite_header(\"Expires\", \"Fri, 01 Jan 1980 00:00:00 GMT\");\n> +\twrite_header(\"Pragma\", \"no-cache\");\n> +\twrite_header(\"Cache-Control\", \"no-cache, max-age=0, must-revalidate\");\n> +}\n> +\n> +static void write_cache_forever(void)\n> +{\n> +\tunsigned long now = time(NULL);\n> +\twrite_header(\"Date\", http_date(now));\n> +\twrite_header(\"Expires\", http_date(now + 31536000));\n> +\twrite_header(\"Cache-Control\", \"public, max-age=31536000\");\n> +}\n> +\n> +static NORETURN void not_found(const char *err, ...)\n> +{\n> +\tva_list params;\n> +\n> +\twrite_status(404, \"Not Found\");\n> +\twrite_nocache();\n> +\tend_headers();\n> +\n> +\tva_start(params, err);\n> +\tif (err && *err) {\n> +\t\tvsnprintf(buffer, sizeof(buffer), err, params);\n> +\t\tfprintf(stderr, \"%s\\n\", buffer);\n> +\t}\n> +\tva_end(params);\n> +\texit(0);\n> +}\n> +\n> +static void write_file(const char *the_type, const char *name)\n> +{\n> +\tconst char *p = git_path(\"%s\", name);\n> +\tint fd;\n> +\tstruct stat sb;\n> +\tuintmax_t remaining;\n> +\n> +\tfd = open(p, O_RDONLY);\n> +\tif (fd < 0)\n> +\t\tnot_found(\"Cannot open '%s': %s\", p, strerror(errno));\n> +\tif (fstat(fd, &sb) < 0)\n> +\t\tdie_errno(\"Cannot stat '%s'\", p);\n> +\tremaining = (uintmax_t)sb.st_size;\n> +\n> +\twrite_header(content_type, the_type);\n> +\twrite_header(\"Last-Modified\", http_date(sb.st_mtime));\n> +\tformat_write(\"Content-Length: %\" PRIuMAX \"\\r\\n\", remaining);\n> +\tend_headers();\n> +\n> +\twhile (remaining) {\n> +\t\tssize_t n = xread(fd, buffer, sizeof(buffer));\n> +\t\tif (n < 0)\n> +\t\t\tdie_errno(\"Cannot read '%s'\", p);\n> +\t\tn = safe_write(1, buffer, n);\n> +\t\tif (n <= 0)\n> +\t\t\tbreak;\n> +\t}\n> +\tclose(fd);\n> +}\n> +\n> +static void get_text_file(char *name)\n> +{\n> +\twrite_nocache();\n> +\twrite_file(\"text/plain; charset=utf-8\", name);\n> +}\n> +\n> +static void get_loose_object(char *name)\n> +{\n> +\twrite_cache_forever();\n> +\twrite_file(\"application/x-git-loose-object\", name);\n> +}\n> +\n> +static void get_pack_file(char *name)\n> +{\n> +\twrite_cache_forever();\n> +\twrite_file(\"application/x-git-packed-objects\", name);\n> +}\n> +\n> +static void get_idx_file(char *name)\n> +{\n> +\twrite_cache_forever();\n> +\twrite_file(\"application/x-git-packed-objects-toc\", name);\n> +}\n> +\n> +static int show_text_ref(const char *name, const unsigned char *sha1,\n> +\tint flag, void *cb_data)\n> +{\n> +\tstruct object *o = parse_object(sha1);\n> +\tif (!o)\n> +\t\treturn 0;\n> +\n> +\tformat_write(\"%s\\t%s\\n\", sha1_to_hex(sha1), name);\n> +\tif (o->type == OBJ_TAG) {\n> +\t\to = deref_tag(o, name, 0);\n> +\t\tif (!o)\n> +\t\t\treturn 0;\n> +\t\tformat_write(\"%s\\t%s^{}\\n\", sha1_to_hex(o->sha1), name);\n> +\t}\n> +\n> +\treturn 0;\n> +}\n> +\n> +static void get_info_refs(char *arg)\n> +{\n> +\twrite_nocache();\n> +\twrite_header(content_type, \"text/plain; charset=utf-8\");\n> +\tend_headers();\n> +\n> +\tfor_each_ref(show_text_ref, NULL);\n> +}\n> +\n> +static void get_info_packs(char *arg)\n> +{\n> +\tsize_t objdirlen = strlen(get_object_directory());\n> +\tstruct packed_git *p;\n> +\n> +\twrite_nocache();\n> +\twrite_header(content_type, \"text/plain; charset=utf-8\");\n> +\tend_headers();\n> +\n> +\tprepare_packed_git();\n> +\tfor (p = packed_git; p; p = p->next) {\n> +\t\tif (!p->pack_local)\n> +\t\t\tcontinue;\n> +\t\tformat_write(\"P %s\\n\", p->pack_name + objdirlen + 6);\n> +\t}\n> +\tsafe_write(1, \"\\n\", 1);\n> +}\n> +\n> +static NORETURN void die_webcgi(const char *err, va_list params)\n> +{\n> +\twrite_status(500, \"Internal Server Error\");\n> +\twrite_nocache();\n> +\tend_headers();\n> +\n> +\tvsnprintf(buffer, sizeof(buffer), err, params);\n> +\tfprintf(stderr, \"fatal: %s\\n\", buffer);\n> +\texit(0);\n> +}\n> +\n> +static struct service_cmd {\n> +\tconst char *method;\n> +\tconst char *pattern;\n> +\tvoid (*imp)(char *);\n> +} services[] = {\n> +\t{\"GET\", \"/HEAD$\", get_text_file},\n> +\t{\"GET\", \"/info/refs$\", get_info_refs},\n> +\t{\"GET\", \"/objects/info/packs$\", get_info_packs},\n> +\t{\"GET\", \"/objects/info/[^/]*$\", get_text_file},\n> +\t{\"GET\", \"/objects/[0-9a-f]{2}/[0-9a-f]{38}$\", get_loose_object},\n> +\t{\"GET\", \"/objects/pack/pack-[0-9a-f]{40}\\\\.pack$\", get_pack_file},\n> +\t{\"GET\", \"/objects/pack/pack-[0-9a-f]{40}\\\\.idx$\", get_idx_file}\n> +};\n> +\n> +int main(int argc, char **argv)\n> +{\n> +\tchar *dir = getenv(\"PATH_TRANSLATED\");\n> +\tchar *input_method = getenv(\"REQUEST_METHOD\");\n> +\tstruct service_cmd *cmd = NULL;\n> +\tchar *cmd_arg = NULL;\n> +\tint i;\n> +\n> +\tset_die_routine(die_webcgi);\n> +\n> +\tif (!dir)\n> +\t\tdie(\"No PATH_TRANSLATED from server\");\n> +\tif (!input_method)\n> +\t\tdie(\"No REQUEST_METHOD from server\");\n> +\tif (!strcmp(input_method, \"HEAD\"))\n> +\t\tinput_method = \"GET\";\n> +\n> +\tfor (i = 0; i < ARRAY_SIZE(services); i++) {\n> +\t\tstruct service_cmd *c = &services[i];\n> +\t\tregex_t re;\n> +\t\tregmatch_t out[1];\n> +\n> +\t\tif (regcomp(&re, c->pattern, REG_EXTENDED))\n> +\t\t\tdie(\"Bogus regex in service table: %s\", c->pattern);\n> +\t\tif (!regexec(&re, dir, 1, out, 0)) {\n> +\t\t\tsize_t n = out[0].rm_eo - out[0].rm_so;\n> +\n> +\t\t\tif (strcmp(input_method, c->method)) {\n> +\t\t\t\tconst char *proto = getenv(\"SERVER_PROTOCOL\");\n> +\t\t\t\tif (proto && !strcmp(proto, \"HTTP/1.1\"))\n> +\t\t\t\t\twrite_status(405, \"Method Not Allowed\");\n> +\t\t\t\telse\n> +\t\t\t\t\twrite_status(400, \"Bad Request\");\n> +\t\t\t\twrite_nocache();\n> +\t\t\t\tend_headers();\n> +\t\t\t\treturn 0;\n> +\t\t\t}\n> +\n> +\t\t\tcmd = c;\n> +\t\t\tcmd_arg = xmalloc(n);\n> +\t\t\tstrncpy(cmd_arg, dir + out[0].rm_so + 1, n);\n> +\t\t\tcmd_arg[n] = '\\0';\n> +\t\t\tdir[out[0].rm_so] = 0;\n> +\t\t\tbreak;\n> +\t\t}\n> +\t\tregfree(&re);\n> +\t}\n> +\n> +\tif (!cmd)\n> +\t\tnot_found(\"Request not supported: '%s'\", dir);\n> +\n> +\tsetup_path();\n> +\tif (!enter_repo(dir, 0))\n> +\t\tnot_found(\"Not a git repository: '%s'\", dir);\n> +\n> +\tcmd->imp(cmd_arg);\n> +\treturn 0;\n> +}\n"},{"id":"124438","messageId":"fabb9a1e0910090101g2de58824p6cfdea86c98e0191@mail.gmail.com","threadId":"21164","inReplyTo":"1255065768-10428-2-git-send-email-spearce@spearce.org","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2009-10-09T08:01:02Z","receivedAt":"2009-10-09T08:01:02Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nI had some spare time, I hope these comments from someone that is not\ntoo familiar with the protocol are helpful :).\n\nOn Fri, Oct 9, 2009 at 07:22, Shawn O. Pearce <spearce@spearce.org> wrote:\n> +Compatible clients must expand\n> +'$GIT_URL/info/refs' as 'foo/info/refs' and not 'foo//info/refs'.\n\nDoes this not need s/must/MUST/\n\n> +       S: ....# service=git-upload-pack\n> +       S: ....95dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint\\0 multi_ack\n> +       S: ....d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\n> +       S: ....2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0\n> +       S: ....a3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}\n\nShouldn't this contain HEAD as the first ref?\n\n> +       ref_list       = empty_list | populated_list\n> +\n> +       empty_list     = PKT-LINE(id SP \"capabilities^{}\" NUL cap_list LF)\n> +\n> +       non_empty_list = PKT-LINE(id SP name NUL cap_list LF)\n> +                        *ref_record\n\nDoes this need a s/non_empty_list/populated_list/ ?\n\n> +       cap_list      = *(SP capability) SP\n\nYou never define capability.\n\n> + (c) Send one $GIT_URL/git-upload-pack request:\n\nI don't think you documented what $GIT_URL/git-upload-pack means.\n\n> +     If the client has sent 256 HAVE commits and has not yet\n> +     received one of those back from S_COMMON, or the client has\n> +     emptied C_PENDING it should include a \"done\" command to let\n> +     the server know it won't proceed:\n> +\n> +       C: 0009done\n\nThis should probably move down to after you define what S_COMMON is in\nthe first place.\n\n\n> +     Here a \"closed set of objects\" is defined to have at least\n> +     one path from every WANT to at least one COMMON object.\n\nA 'path from' is perhaps a bit unclear.\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"124439","messageId":"fabb9a1e0910090109o3ea0c08eo7991fbab34311381@mail.gmail.com","threadId":"21164","inReplyTo":"fabb9a1e0910090101g2de58824p6cfdea86c98e0191@mail.gmail.com","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2009-10-09T08:09:22Z","receivedAt":"2009-10-09T08:09:22Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Fri, Oct 9, 2009 at 10:01, Sverre Rabbelier <srabbelier@gmail.com> wrote:\n>> + (c) Send one $GIT_URL/git-upload-pack request:\n>\n> I don't think you documented what $GIT_URL/git-upload-pack means.\n\nAh, I didn't realize until I read 4/4 that this is just a regular\nrequest to the 'http://<host>:<port>/git-upload-pack' url, I was\nconfused by the need to query\n\"http://<host>:<port>/info/refs?service=git-upload-pack\".\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"124441","messageId":"loom.20091009T104530-586@post.gmane.org","threadId":"21164","inReplyTo":"1255065768-10428-2-git-send-email-spearce@spearce.org","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Alex Blewitt","fromEmail":"alex.blewitt@gmail.com","sentAt":"2009-10-09T08:54:17Z","receivedAt":"2009-10-09T08:54:17Z","isPatch":true,"sender":{"key":"alex.blewitt@gmail.com","avatar":"https://gravatar.com/avatar/fb95a3b593b290f03a8d3b022c20b2825205702c5651f731f65d33512dfe6ab2?d=mp&s=160"},"body":"Shawn O. Pearce <spearce <at> spearce.org> writes:\n\n> +URL Format\n> +----------\n> +\n> +URLs for Git repositories accessed by HTTP use the standard HTTP\n> +URL syntax documented by RFC 1738, so they are of the form:\n> +\n> +  http://<host>:<port>/<path>\n> +\n> +Within this documentation the placeholder $GIT_URL will stand for\n> +the http:// repository URL entered by the end-user.\n\nIt's worth making clear here that $GIT_URL will be the path to the repository,\nrather than necessarily just the host upon which the server sits. Perhaps\nincluding an example, like http://example:8080/repos/example.git\nwould make it clearer that there can be a path (and so leading to\na request like http://example:8080/repos/example.git/info/refs?service=...\n\nIt's also worth clarifying, therefore, that multiple repositories can be served\nby the same process (as with the git server today) by using different path(s).\nAnd for those that are interested in submodules, it's worth confirming that\nhttp://example/repos/master.git/child.git/info/refs?service= will ensure \nthat the repository is the 'child' git rather than anything else.\n\n> HEX = [0-9a-f]\n\nIs there any reason not to support A-F as well in the hex spec, even if they\nSHOULD use a-f? This may limit the appeal for some case-insensitive systems.\n\nIt would also be good to document, like with the git daemon, whether all\nrepositories under a path are exported or only those that have the magic\nsetting in the config like git-daemon-export-ok.\n\nLastly, it would be good to clarify when the result of this GET/POST exchange\nis a text-based (and encoded in UTF-8) vs when binary data is returned; we \ndon't want to get into the state where we're returning binary data and \npretending that it's UTF-8.\n\nAlex\n"},{"id":"124522","messageId":"m3eipcgyfv.fsf@localhost.localdomain","threadId":"21164","inReplyTo":"1255065768-10428-2-git-send-email-spearce@spearce.org","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-10-09T19:27:35Z","receivedAt":"2009-10-09T19:27:35Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"\"Shawn O. Pearce\" <spearce@spearce.org> writes:\n\n> +\tempty_list     = PKT-LINE(id SP \"capabilities^{}\" NUL cap_list LF)\n> +\n> +\tnon_empty_list = PKT-LINE(id SP name NUL cap_list LF)\n> +\t                 *ref_record\n> +\n> +\tcap_list      = *(SP capability) SP\n\nErrr... are you sure?  Because from examples it looks like cap_list\n(capabilities list) is a list of space *separated* capabilities, while\nthe above requires also both leading and trailing space.  Shouldn't it\nbe\n\n\tcap_list      = capability *(SP capability)\n\nAlso the format for capability is not defined; I guess only \na-z, 0-9, '-' and '_' are allowed in capability name.\n\n\nBTW. is it possible to not have capability list?\n\n> +\tHEX           = \"0\"..\"9\" | \"a\"..\"f\"\n\nDo you plan allowing also upper case letters, while server and client\nSHOULD use lowercase?  Because if you do, then RFC 5234 which defines\nABNF you seem to be using here has HEXDIG defined.\n\n> +\tNL            = <US-ASCII NUL, null (0)>\n\nWhy not NUL?\n\n> +\tLF            = <US-ASCII LF,  linefeed (10)>\n> +\tSP            = <US-ASCII SP,  horizontal-tab (9)>\n                                       ^^^^^^^^^^^^^^-- o'rly?\n\nThose are pre-defined in ABNF, e.g.\n\n\tSP             =  %x20\n\n> +References\n> +----------\n> +\n> +link:http://www.ietf.org/rfc/rfc1738.txt[RFC 1738: Uniform Resource Locators (URL)]\n> +link:http://www.ietf.org/rfc/rfc2616.txt[RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1]\n\nYou should also reference the following RFCs:\n * \"RFC 5234: Augmented BNF for Syntax Specifications: ABNF\"\n * \"RFC 2119: Key words for use in RFCs to Indicate Requirement Levels\"\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"124523","messageId":"20091009195035.GA15153@coredump.intra.peff.net","threadId":"21164","inReplyTo":"1255065768-10428-2-git-send-email-spearce@spearce.org","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-10-09T19:50:36Z","receivedAt":"2009-10-09T19:50:36Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Oct 08, 2009 at 10:22:45PM -0700, Shawn O. Pearce wrote:\n\n> +Servers MUST NOT require HTTP cookies for the purposes of\n> +authentication or access control.\n> [...]\n> +Servers MUST NOT require HTTP cookies in order to function correctly.\n> +Clients MAY store and forward HTTP cookies during request processing\n> +as described by RFC 2616 (HTTP/1.1).  Servers SHOULD ignore any\n> +cookies sent by a client.\n\nWhy not? I can grant that the current git implementation probably can't\nhandle it, but keep in mind this is talking about the protocol and not\nthe implementation. And I can see it being useful for sites like github\nwhich already have a cookie-based login. Adapting the client to handle\nthis case would not be too difficult (it would just mean keeping cookie\nstate in a file between runs, or even just pulling it out of the normal\nbrowser's cookie store). And people whose client didn't do this would\nsimply get an \"access denied\" response code.\n\nIs there a technical reason not to allow it?\n\n-Peff\n"},{"id":"124525","messageId":"7vskdss3ei.fsf@alter.siamese.dyndns.org","threadId":"21164","inReplyTo":"1255065768-10428-2-git-send-email-spearce@spearce.org","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-10-09T20:44:53Z","receivedAt":"2009-10-09T20:44:53Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Shawn O. Pearce\" <spearce@spearce.org> writes:\n\n> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>\n\nNice write-up.\n\n>  Documentation/technical/http-protocol.txt |  542 +++++++++++++++++++++++++++++\n>  1 files changed, 542 insertions(+), 0 deletions(-)\n>  create mode 100644 Documentation/technical/http-protocol.txt\n>\n> diff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\n> new file mode 100644\n> index 0000000..316d9b6\n> --- /dev/null\n> +++ b/Documentation/technical/http-protocol.txt\n> @@ -0,0 +1,542 @@\n> +HTTP transfer protocols\n> +=======================\n> ...\n> +As a design feature smart clients can automatically upgrade \"dumb\"\n> +protocol URLs to smart URLs.  This permits all users to have the\n> +same published URL, and the peers automatically select the most\n> +efficient transport available to them.\n\nThe first sentence feels backwards although the conclusion in the second\nsentence is true.  It is more like smart ones trying smart protocol first,\nand downgrading to \"dumb\" after noticing that the server is not smart.\n\n> +Authentication\n> +--------------\n> ...\n> +Clients SHOULD support Basic authentication as described by RFC 2616.\n> +Servers SHOULD support Basic authentication by relying upon the\n> +HTTP server placed in front of the Git server software.\n\nIt is perfectly fine to make it a requirement for a server to support the\nBasic authentication, but should you make it a requirement that the\nsupport is done by a specific implementation, i.e. \"by relying upon...\"?\n\n> +Session State\n> +-------------\n> ...\n> +retained and managed by the client process.  This permits simple\n> +round-robin load-balancing on the server side, without needing to\n> +worry about state mangement.\n\ns/mangement/management/;\n\n> +pkt-line Format\n> +---------------\n> ...\n> +Examples (as C-style strings):\n> +\n> +  pkt-line          actual value\n> +  ---------------------------------\n> +  \"0006a\\n\"         \"a\\n\"\n> +  \"0005a\"           \"a\"\n> +  \"000bfoobar\\n\"    \"foobar\\n\"\n> +  \"0004\"            \"\"\n> +\n> +A pkt-line with a length of 0 (\"0000\") is a special case and MUST\n> +be treated as a message break or terminator in the payload.\n\nIsn't this \"MUST be\" wrong?\n\nIt is not an advice to the implementors, but the protocol specification\nitself defines what the flush packet means.  IOW, \"The author of this\nspecification, Shawn, MUST treat a flush packet as a message break or\nterminator in the payload, when designing this protocol.\"\n\n> +General Request Processing\n> +--------------------------\n> +\n> +Except where noted, all standard HTTP behavior SHOULD be assumed\n> +by both client and server.  This includes (but is not necessarily\n> +limited to):\n> +\n> +If there is no repository at $GIT_URL, the server MUST respond with\n> +the '404 Not Found' HTTP status code.\n\nWe may also want to add\n\n    If there is no object at $GIT_URL/some/path, the server MUST respond\n    with the '404 Not Found' HTTP status code.\n\nto help dumb clients.\n\n> +Dumb Clients\n> +~~~~~~~~~~~~\n> +\n> +HTTP clients that only support the \"dumb\" protocol MUST discover\n> +references by making a request for the special info/refs file of\n> +the repository.\n> +\n> +Dumb HTTP clients MUST NOT include search/query parameters when\n> +fetching the info/refs file.  (That is, '?' must not appear in the\n> +requested URL.)\n\nIt is unclear if '?' can be part of $GIT_URL. E.g.\n\n    $ wget http://example.xz/serve.cgi?path=git.git/info/refs\n    $ git clone http://example.xz/serve.cgi?path=git.git\n\nIt might be clearer to just say\n\n    Dumb HTTP clients MUST make a GET request against $GIT_URL/info/refs,\n    without any search/query parameters.  I.e.\n\n\tC: GET $GIT_URL/info/refs HTTP/1.0\n\nto also exclude methods other than GET.\n\n> +\tC: GET $GIT_URL/info/refs HTTP/1.0\n> +\n> +\tS: 200 OK\n> ...\n> +When examining the response clients SHOULD only examine the HTTP\n> +status code.  Valid responses are '200 OK', or '304 Not Modified'.\n\nIsn't 401 (\"Ah, I was given a wrong URL\") and 403 (\"Ok, I do not have an\naccess to this repository\") also valid?\n\n> +The returned content is a UNIX formatted text file describing\n> +each ref and its known value.  The file SHOULD be sorted by name\n> +according to the C locale ordering.  The file SHOULD NOT include\n> +the default ref named 'HEAD'.\n\nI know you said \"known\" to imply \"concurrent operations may change it\nwhile the server is serving this client\", but it feels rather awkward.\n\n> +Smart Server Response\n> +^^^^^^^^^^^^^^^^^^^^^\n> +\n> +Smart servers MUST respond with the smart server reply format.\n> +If the server does not recognize the requested service name, or the\n> +requested service name has been disabled by the server administrator,\n> +the server MUST respond with the '403 Forbidden' HTTP status code.\n\nThis is a bit confusing.\n\nIf you as a server administrator want to disable the smart upload-pack for\none repository (but not for other repositories), you would not be able to\nforce smart clients to fall back to the dumb protocol by giving \"403\" for\nthat repository.\n\nMaybe in 2 years somebody smarter than us will have invented a more\nefficient git-upload-pack-2 service, which is the only fetch protocol his\nserver supports other than dumb.  If your v1 smart client asks for the\noriginal git-upload-pack service and gets a \"403\", you won't be able to\nfall back to \"dumb\".\n\nThe solution for such cases likely is to pretend as if you are a dumb\nserver for the smart request.  That unfortunately means that the first\nsentence is misleading, and the second sentence is also an inappropriate\nadvice.\n\n> +The Content-Type MUST be 'application/x-$servicename-advertisement'.\n> +Clients SHOULD fall back to the dumb protocol if another content\n> +type is returned.  When falling back to the dumb protocol clients\n> +SHOULD NOT make an additional request to $GIT_URL/info/refs, but\n> +instead SHOULD use the response already in hand.  Clients MUST NOT\n> +continue if they do not support the dumb protocol.\n\nThe part I commented on (the beginning of Smart Server Response) was\nwritten as a generic description, not specific to git-upload-pack service,\nand the beginning of this paragraph also pretends to be a generic\ndescription, but it is misleading.  This is a specific instruction to the\nclients that asked for git-upload-pack service and got a dumb server\nresponse (if the above were talking about something other than upload-pack\nservice, there is no guarantee that \"response already in hand\" is useful\nto talk to dumb servers).\n\n> +The returned response is a pkt-line stream describing each ref and\n> +its known value.  The stream SHOULD be sorted by name according to\n> +the C locale ordering.  The stream SHOULD include the default ref\n> +named 'HEAD' as the first ref.  The stream MUST include capability\n> +declarations behind a NUL on the first ref.\n> +\n> +\tsmart_reply    = PKT-LINE(\"# service=$servicename\" LF)\n> +\t                 ref_list\n> +\t                 \"0000\"\n> +\tref_list       = empty_list | populated_list\n> +\n> +\tempty_list     = PKT-LINE(id SP \"capabilities^{}\" NUL cap_list LF)\n> +\n> +\tnon_empty_list = PKT-LINE(id SP name NUL cap_list LF)\n> +\t                 *ref_record\n> +\n> +\tcap_list      = *(SP capability) SP\n> +\tref_record    = any_ref | peeled_ref\n> +\n> +\tany_ref       = PKT-LINE(id SP name LF)\n> +\tpeeled_ref    = PKT-LINE(id SP name LF)\n> +\t                PKT-LINE(id SP name \"^{}\" LF\n> +\tid            = 40*HEX\n> +\n> +\tHEX           = \"0\"..\"9\" | \"a\"..\"f\"\n> +\tNL            = <US-ASCII NUL, null (0)>\n> +\tLF            = <US-ASCII LF,  linefeed (10)>\n> +\tSP            = <US-ASCII SP,  horizontal-tab (9)>\n\nDid you define what \"populated_list\" is?\n\n> +Smart Service git-upload-pack\n> +------------------------------\n> +This service reads from the remote repository.\n\nThe wording \"remote repository\" felt confusing.  I know it is \"from the\nrepository served by the server\", but if it were named without\n\"upload-pack\", I might have mistaken that you are allowing to proxy a\nrequest to access a third-party repository by this server.  The same\ncomment applies to the git-receive-pack service.\n\n> +Capability include-tag\n> +~~~~~~~~~~~~~~~~~~~~~~\n> +\n> +When packing an object that an annotated tag points at, include the\n> +tag object too.  Clients can request this if they want to fetch\n> +tags, but don't know which tags they will need until after they\n> +receive the branch data.  By enabling include-tag an entire call\n> +to upload-pack can be avoided.\n> +\n\nI think you are avoiding an \"extra\" call; you would need one entire call\nto upload-pack anyway for the primary transfer.\n"},{"id":"124563","messageId":"slrnhd0nfv.tq2.antti-juhani@kukkaseppele.kaijanaho.fi","threadId":"21164","inReplyTo":"7vskdss3ei.fsf@alter.siamese.dyndns.org","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Antti-Juhani Kaijanaho","fromEmail":"antti-juhani@kaijanaho.fi","sentAt":"2009-10-10T10:12:15Z","receivedAt":"2009-10-10T10:12:15Z","isPatch":true,"sender":{"key":"antti-juhani@kaijanaho.fi","avatar":null},"body":"On 2009-10-09, Junio C Hamano <gitster@pobox.com> wrote:\n>> +If there is no repository at $GIT_URL, the server MUST respond with\n>> +the '404 Not Found' HTTP status code.\n>\n> We may also want to add\n>\n>     If there is no object at $GIT_URL/some/path, the server MUST respond\n>     with the '404 Not Found' HTTP status code.\n>\n> to help dumb clients.\n\nIn both cases - is it really necessary to forbid the use of 410 (Gone)?\n\n-- \nMr. Antti-Juhani Kaijanaho, Jyvaskyla, Finland\n"},{"id":"124566","messageId":"be6fef0d0910100517h1a8b9551jc890251665bbcd69@mail.gmail.com","threadId":"21164","inReplyTo":"1255065768-10428-2-git-send-email-spearce@spearce.org","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2009-10-10T12:17:10Z","receivedAt":"2009-10-10T12:17:10Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Hi,\n\nOn Fri, Oct 9, 2009 at 1:22 PM, Shawn O. Pearce <spearce@spearce.org> wrote:\n> +Smart Clients\n> +~~~~~~~~~~~~~\n> +\n> +HTTP clients that support the \"smart\" protocol (or both the\n> +\"smart\" and \"dumb\" protocols) MUST discover references by making\n> +a paramterized request for the info/refs file of the repository.\n\ns/paramterized/parameterized/ -- missing 'e'.\n\n-- \nCheers,\nRay Chuan\n"},{"id":"125084","messageId":"20091015163904.GN10505@spearce.org","threadId":"21164","inReplyTo":"loom.20091009T104530-586@post.gmane.org","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-10-15T16:39:04Z","receivedAt":"2009-10-15T16:39:04Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Alex Blewitt <Alex.Blewitt@gmail.com> wrote:\n> Shawn O. Pearce <spearce <at> spearce.org> writes:\n> \n> > +URL Format\n> > +----------\n> \n> It's worth making clear here that $GIT_URL will be the path to the repository,\n...\n\nThanks, noted.\n\n> > HEX = [0-9a-f]\n> \n> Is there any reason not to support A-F as well in the hex spec, even if they\n> SHOULD use a-f?\n\nConsistency.  I'd rather be strict and say HEX is [0-9a-f] and\ndemand that everyone try to standardize on the lower case form.\n\n> This may limit the appeal for some case-insensitive systems.\n\nGiven that this particular notation of HEX is *only* used within\nthe protocol body to describe SHA-1 IDs, it won't make it to the\nfile system as-is.\n\nA conforming Git implementation would first validate that this is in\nfact a SHA-1 ID, likely translate it into a binary representation\n(that is collapse the 40 byte hex to a 20 byte binary), and then\nreformat it as a file system path if its looking for a loose object.\n \n> It would also be good to document, like with the git daemon, whether all\n> repositories under a path are exported or only those that have the magic\n> setting in the config like git-daemon-export-ok.\n\nThis isn't something that matters to the protocol specification.\nIts a server access control, not protocol detail.\n\nReally, its an implementation detail of git-http-backend in git.git,\nor of the RepositoryResolver and UploadPackFactory in JGit.\n\nTherefore, its not going to be documented in this document.\n \n> Lastly, it would be good to clarify when the result of this GET/POST exchange\n> is a text-based (and encoded in UTF-8) vs when binary data is returned; we \n> don't want to get into the state where we're returning binary data and \n> pretending that it's UTF-8.\n\nOh, right.\n\n-- \nShawn.\n"},{"id":"125085","messageId":"20091015165228.GO10505@spearce.org","threadId":"21164","inReplyTo":"20091009195035.GA15153@coredump.intra.peff.net","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-10-15T16:52:28Z","receivedAt":"2009-10-15T16:52:28Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Jeff King <peff@peff.net> wrote:\n> On Thu, Oct 08, 2009 at 10:22:45PM -0700, Shawn O. Pearce wrote:\n> > +Servers MUST NOT require HTTP cookies for the purposes of\n> > +authentication or access control.\n> > [...]\n> > +Servers MUST NOT require HTTP cookies in order to function correctly.\n> \n> Why not? I can grant that the current git implementation probably can't\n> handle it, but keep in mind this is talking about the protocol and not\n> the implementation.\n\nGood point... this document is about trying to explain the common\nfunctionality that everyone can agree on.\n\n> And I can see it being useful for sites like github\n> which already have a cookie-based login.\n\nWhat I'm concerned about is using the cookie jar.  My Mac OS X\nlaptop has 5 browsers installed, each with their own #@!*! cookie\njar: Safari, Opera, Firefox, Camino, Google Chrome.  How the hell\nis the git client going to be able to use those cookies in order\nto interact with a website that requires cookie authentication?\n\n> Adapting the client to handle\n> this case would not be too difficult (it would just mean keeping cookie\n> state in a file between runs,\n\nSaving our own cookie jar is easy, libcurl has some limited cookie\njar support already built in.  We just have to enable it.\n\n> or even just pulling it out of the normal\n> browser's cookie store).\n\nSee above, I don't think this will be very easy.\n\n> And people whose client didn't do this would\n> simply get an \"access denied\" response code.\n\nAnd then they will email git ML or ask on #git why their git client\ncan't speak to some random website... and its because they used\n\"lynx\" or yet-another-browser whose cookie jar format we can't read.\n\n> Is there a technical reason not to allow it?\n\nNot technical, but I want to reduce the amount of complexity that\na conforming client has to deal with to reduce support costs for\neveryone involved.\n\nI weakend the sections on cookies:\n\n+ Authentication\n+ --------------\n....\n+ Servers SHOULD NOT require HTTP cookies for the purposes of\n+ authentication or access control.\n\nand that's all we say on the matter.  I took out the Servers MUST\nNOT line under session state.\n\n-- \nShawn.\n"},{"id":"125089","messageId":"20091015173902.GA22262@sigill.intra.peff.net","threadId":"21164","inReplyTo":"20091015165228.GO10505@spearce.org","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-10-15T17:39:02Z","receivedAt":"2009-10-15T17:39:02Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Oct 15, 2009 at 09:52:28AM -0700, Shawn O. Pearce wrote:\n\n> > And I can see it being useful for sites like github\n> > which already have a cookie-based login.\n> \n> What I'm concerned about is using the cookie jar.  My Mac OS X\n> laptop has 5 browsers installed, each with their own #@!*! cookie\n> jar: Safari, Opera, Firefox, Camino, Google Chrome.  How the hell\n> is the git client going to be able to use those cookies in order\n> to interact with a website that requires cookie authentication?\n\nSure, it is obviously something that an implementation will have to deal\nwith. Either through manual configuration by the user or some\nauto-detection magic that tries to cover every case (and I suspect if we\nreally wanted to do this, a patch to libcurl to handle different cookie\njar formats would probably be the best way to go).\n\nBut my main point was that it is an implementation issue, not a protocol\nissue. The lines are a little blurry for us because there really aren't\nvery many git implementations, but I think your document is an attempt\nto document just the protocol to allow interoperability between clients.\n\nBut I think you got my point:\n\n> Not technical, but I want to reduce the amount of complexity that\n> a conforming client has to deal with to reduce support costs for\n> everyone involved.\n> \n> I weakend the sections on cookies:\n> \n> + Authentication\n> + --------------\n> ....\n> + Servers SHOULD NOT require HTTP cookies for the purposes of\n> + authentication or access control.\n> \n> and that's all we say on the matter.  I took out the Servers MUST\n> NOT line under session state.\n\nI think this is a good compromise. It's not recommended at this point,\nbut there is no reason to disallow it if both sides can handle the\nnon-protocol part (i.e., storing and managing cookies). Thanks.\n\n-Peff\n"},{"id":"125140","messageId":"4AD80BBD.8080504@zytor.com","threadId":"21164","inReplyTo":"slrnhd0nfv.tq2.antti-juhani@kukkaseppele.kaijanaho.fi","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"H. Peter Anvin","fromEmail":"hpa@zytor.com","sentAt":"2009-10-16T05:59:25Z","receivedAt":"2009-10-16T05:59:25Z","isPatch":true,"sender":{"key":"hpa@zytor.com","avatar":null},"body":"On 10/10/2009 03:12 AM, Antti-Juhani Kaijanaho wrote:\n> On 2009-10-09, Junio C Hamano <gitster@pobox.com> wrote:\n>>> +If there is no repository at $GIT_URL, the server MUST respond with\n>>> +the '404 Not Found' HTTP status code.\n>>\n>> We may also want to add\n>>\n>>     If there is no object at $GIT_URL/some/path, the server MUST respond\n>>     with the '404 Not Found' HTTP status code.\n>>\n>> to help dumb clients.\n> \n> In both cases - is it really necessary to forbid the use of 410 (Gone)?\n> \n\n410 means \"we once had it, it's no longer here, no idea where it went.\"\n It's a largely useless code...\n\n-- \nH. Peter Anvin, Intel Open Source Technology Center\nI work for Intel.  I don't speak on their behalf.\n"},{"id":"125143","messageId":"20091016071942.GC3009@glandium.org","threadId":"21164","inReplyTo":"4AD80BBD.8080504@zytor.com","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Mike Hommey","fromEmail":"mh@glandium.org","sentAt":"2009-10-16T07:19:42Z","receivedAt":"2009-10-16T07:19:42Z","isPatch":true,"sender":{"key":"mh@glandium.org","avatar":"https://avatars.githubusercontent.com/u/1038527?v=4"},"body":"On Thu, Oct 15, 2009 at 10:59:25PM -0700, H. Peter Anvin wrote:\n> On 10/10/2009 03:12 AM, Antti-Juhani Kaijanaho wrote:\n> > On 2009-10-09, Junio C Hamano <gitster@pobox.com> wrote:\n> >>> +If there is no repository at $GIT_URL, the server MUST respond with\n> >>> +the '404 Not Found' HTTP status code.\n> >>\n> >> We may also want to add\n> >>\n> >>     If there is no object at $GIT_URL/some/path, the server MUST respond\n> >>     with the '404 Not Found' HTTP status code.\n> >>\n> >> to help dumb clients.\n> > \n> > In both cases - is it really necessary to forbid the use of 410 (Gone)?\n> > \n> \n> 410 means \"we once had it, it's no longer here, no idea where it went.\"\n>  It's a largely useless code...\n\nThere is an additional meaning to it, that is \"it will never ever\nreturn\". It thus has a stronger meaning than 404. Sadly, not even search\nengine spiders consider it as a hint to not crawl there in the future...\n\nMike\n"},{"id":"125172","messageId":"20091016142135.GR10505@spearce.org","threadId":"21164","inReplyTo":"20091016071942.GC3009@glandium.org","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2009-10-16T14:21:35Z","receivedAt":"2009-10-16T14:21:35Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Mike Hommey <mh@glandium.org> wrote:\n> On Thu, Oct 15, 2009 at 10:59:25PM -0700, H. Peter Anvin wrote:\n> > On 10/10/2009 03:12 AM, Antti-Juhani Kaijanaho wrote:\n> > > On 2009-10-09, Junio C Hamano <gitster@pobox.com> wrote:\n> > >>> +If there is no repository at $GIT_URL, the server MUST respond with\n> > >>> +the '404 Not Found' HTTP status code.\n> > >>\n> > >> We may also want to add\n> > >>\n> > >>     If there is no object at $GIT_URL/some/path, the server MUST respond\n> > >>     with the '404 Not Found' HTTP status code.\n> > >>\n> > >> to help dumb clients.\n> > > \n> > > In both cases - is it really necessary to forbid the use of 410 (Gone)?\n\nMy original text got taken a bit out of context here.  I guess MUST\nwas too strong of a word.  I more ment something like:\n\n  If there is no repository at $GIT_URL, the server MUST NOT respond\n  with '200 OK' and a valid info/refs response.  A server SHOULD\n  respond with '404 Not Found', '410 Gone', or any other suitable\n  HTTP status code which does not imply the resource exists as\n  requested.\n\n> > 410 means \"we once had it, it's no longer here, no idea where it went.\"\n> >  It's a largely useless code...\n> \n> There is an additional meaning to it, that is \"it will never ever\n> return\". It thus has a stronger meaning than 404. Sadly, not even search\n> engine spiders consider it as a hint to not crawl there in the future...\n\nI know.  I broke a URL on a site back in Janurary, MSN keeps crawling\nit anyway.  F'king spiders.\n\n-- \nShawn.\n"},{"id":"125178","messageId":"slrnhdh0ec.4du.antti-juhani@kukkaseppele.kaijanaho.fi","threadId":"21164","inReplyTo":"4AD80BBD.8080504@zytor.com","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Antti-Juhani Kaijanaho","fromEmail":"antti-juhani@kaijanaho.fi","sentAt":"2009-10-16T14:23:08Z","receivedAt":"2009-10-16T14:23:08Z","isPatch":true,"sender":{"key":"antti-juhani@kaijanaho.fi","avatar":null},"body":"On 2009-10-16, H. Peter Anvin <hpa@zytor.com> wrote:\n> 410 means \"we once had it, it's no longer here, no idea where it went.\"\n>  It's a largely useless code...\n\nThat's not a reason to forbid it methinks.  And I quite like the difference\nbetween \"oops, mistyped the URI\" and \"oops, that URI is no longer valid\".\n\n-- \nMr. Antti-Juhani Kaijanaho, Jyvaskyla, Finland\n"},{"id":"138706","messageId":"m2md411cc4a1004052157v200f902ek22420456e4a45512@mail.gmail.com","threadId":"21164","inReplyTo":"1255065768-10428-2-git-send-email-spearce@spearce.org","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Scott Chacon","fromEmail":"schacon@gmail.com","sentAt":"2010-04-06T04:57:11Z","receivedAt":"2010-04-06T04:57:11Z","isPatch":true,"sender":{"key":"schacon@gmail.com","avatar":"https://gravatar.com/avatar/9b13a8a078e1dcf8588c4eea9554445d51ebed6c41b51f56f4d96738130b05c6?d=mp&s=160"},"body":"Hey,\n\nOn Thu, Oct 8, 2009 at 10:22 PM, Shawn O. Pearce <spearce@spearce.org> wrote:\n> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>\n> ---\n>  Documentation/technical/http-protocol.txt |  542 +++++++++++++++++++++++++++++\n>  1 files changed, 542 insertions(+), 0 deletions(-)\n>  create mode 100644 Documentation/technical/http-protocol.txt\n\nI just spent a while looking for this in my email archive - why was\nthis document not added to the technical/ dir?  Can we put it there?\n\nScott\n"},{"id":"138713","messageId":"7v1vetkt8i.fsf@alter.siamese.dyndns.org","threadId":"21164","inReplyTo":"m2md411cc4a1004052157v200f902ek22420456e4a45512@mail.gmail.com","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-04-06T06:09:01Z","receivedAt":"2010-04-06T06:09:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Scott Chacon <schacon@gmail.com> writes:\n\n> On Thu, Oct 8, 2009 at 10:22 PM, Shawn O. Pearce <spearce@spearce.org> wrote:\n>> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>\n>> ---\n>>  Documentation/technical/http-protocol.txt |  542 +++++++++++++++++++++++++++++\n>>  1 files changed, 542 insertions(+), 0 deletions(-)\n>>  create mode 100644 Documentation/technical/http-protocol.txt\n>\n> I just spent a while looking for this in my email archive - why was\n> this document not added to the technical/ dir?  Can we put it there?\n\nPerhaps because it was marked as RFC and not much discussion went on?\nSorry, but I cannot keep mental bandwidth to remember the threads from 6\nmonths ago while doing this as a part-time non-job ;-)\n\nI wonder what other three patches were about, at the same time...\n"},{"id":"138751","messageId":"v2wd411cc4a1004060653nd8d8e924t92183c55543e8294@mail.gmail.com","threadId":"21164","inReplyTo":"u2hd411cc4a1004060652k5a7f8ea4l67a9b079963f4dc4@mail.gmail.com","subject":"[RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Scott Chacon","fromEmail":"schacon@gmail.com","sentAt":"2010-04-06T13:53:13Z","receivedAt":"2010-04-06T13:53:13Z","isPatch":true,"sender":{"key":"schacon@gmail.com","avatar":"https://gravatar.com/avatar/9b13a8a078e1dcf8588c4eea9554445d51ebed6c41b51f56f4d96738130b05c6?d=mp&s=160"},"body":"Hey,\n\nOn Mon, Apr 5, 2010 at 11:09 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Scott Chacon <schacon@gmail.com> writes:\n>\n>> On Thu, Oct 8, 2009 at 10:22 PM, Shawn O. Pearce <spearce@spearce.org> wrote:\n>>> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>\n>>> ---\n>>>  Documentation/technical/http-protocol.txt |  542 +++++++++++++++++++++++++++++\n>>>  1 files changed, 542 insertions(+), 0 deletions(-)\n>>>  create mode 100644 Documentation/technical/http-protocol.txt\n>>\n>> I just spent a while looking for this in my email archive - why was\n>> this document not added to the technical/ dir?  Can we put it there?\n>\n> Perhaps because it was marked as RFC and not much discussion went on?\n> Sorry, but I cannot keep mental bandwidth to remember the threads from 6\n> months ago while doing this as a part-time non-job ;-)\n>\n\nI understand, it wasn't meant as a criticism, I was just curious why\nthis file was never included.  That the series was marked as RFC makes\nsense.  Could I request that this one patch be included?  Or if Shawn\nhas a more recent one?  I have found and extracted it and have it in a\ntopic branch locally, but if someone else wanted to reference it to\nimplement the HTTP stuff it would probably be really helpful to at\nleast have something in the main tree.\n\nThanks,\nScott\n"},{"id":"138768","messageId":"7vochwijaz.fsf@alter.siamese.dyndns.org","threadId":"21164","inReplyTo":"v2wd411cc4a1004060653nd8d8e924t92183c55543e8294@mail.gmail.com","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-04-06T17:26:28Z","receivedAt":"2010-04-06T17:26:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Scott Chacon <schacon@gmail.com> writes:\n\n> I understand, it wasn't meant as a criticism, I was just curious why\n> this file was never included.  That the series was marked as RFC makes\n> sense.  Could I request that this one patch be included?  Or if Shawn\n> has a more recent one?\n\nI also understand and I didn't mean to sound as if I took offense.  I very\nmuch appreciate reminders like yours of old discussions and patches that\nwere basically good but did not reach conclusion at the end to avoid\nwasted effort.\n\nA pointer is good, but if you are reviving an old patch, it would be\nmuch easier if you did a resend/forward for people to comment in-line,\nby the way.\n"},{"id":"138869","messageId":"20100408021654.00006eee@unknown","threadId":"21164","inReplyTo":"7vskdss3ei.fsf@alter.siamese.dyndns.org","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2010-04-07T18:16:54Z","receivedAt":"2010-04-07T18:16:54Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Hi,\n\n(I'm reviving this thread to complete the document. What I have right\nnow is available at my github repo; you can see it at\n\n  http://github.com/rctay/git/compare/git/next...feature/http-doc#files_bucket\n\n.\n\nAn inlined patch should be sent in soon.)\n\nOn Fri, 09 Oct 2009 13:44:53 -0700\nJunio C Hamano <gitster@pobox.com> wrote:\n\n> \"Shawn O. Pearce\" <spearce@spearce.org> writes:\n> > diff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\n> > new file mode 100644\n> > index 0000000..316d9b6\n> > --- /dev/null\n> > +++ b/Documentation/technical/http-protocol.txt\n> > @@ -0,0 +1,542 @@\n> > +HTTP transfer protocols\n> > +=======================\n> > ...\n> > +As a design feature smart clients can automatically upgrade \"dumb\"\n> > +protocol URLs to smart URLs.  This permits all users to have the\n> > +same published URL, and the peers automatically select the most\n> > +efficient transport available to them.\n> \n> The first sentence feels backwards although the conclusion in the second\n> sentence is true.  It is more like smart ones trying smart protocol first,\n> and downgrading to \"dumb\" after noticing that the server is not smart.\n\nI think Shawn is trying to describe this from the persepective of the\nclient implementation - a \"dumb\" url is first constructed, then\n\"upgraded\" to a \"smart\" one.\n\n> > +Authentication\n> > +--------------\n> > ...\n> > +Clients SHOULD support Basic authentication as described by RFC 2616.\n> > +Servers SHOULD support Basic authentication by relying upon the\n> > +HTTP server placed in front of the Git server software.\n> \n> It is perfectly fine to make it a requirement for a server to support the\n> Basic authentication, but should you make it a requirement that the\n> support is done by a specific implementation, i.e. \"by relying upon...\"?\n\nI think the term \"Server\" in this document is implied as an amalgam of\nthe HTTP server, and a CGI script/program (\"Git server software\"). I\nthink what Shawn meant was for Basic authentication to be implemented\nat the server layer, not in the CGI scripts/program.\n\n> > +Session State\n> > +-------------\n> > ...\n> > +retained and managed by the client process.  This permits simple\n> > +round-robin load-balancing on the server side, without needing to\n> > +worry about state mangement.\n> \n> s/mangement/management/;\n\nDone.\n\n> > +pkt-line Format\n> > +---------------\n> > ...\n> > +Examples (as C-style strings):\n> > +\n> > +  pkt-line          actual value\n> > +  ---------------------------------\n> > +  \"0006a\\n\"         \"a\\n\"\n> > +  \"0005a\"           \"a\"\n> > +  \"000bfoobar\\n\"    \"foobar\\n\"\n> > +  \"0004\"            \"\"\n> > +\n> > +A pkt-line with a length of 0 (\"0000\") is a special case and MUST\n> > +be treated as a message break or terminator in the payload.\n> \n> Isn't this \"MUST be\" wrong?\n> \n> It is not an advice to the implementors, but the protocol specification\n> itself defines what the flush packet means.  IOW, \"The author of this\n> specification, Shawn, MUST treat a flush packet as a message break or\n> terminator in the payload, when designing this protocol.\"\n\nThis section has been purged; we already have this in\nDocumentation/technical/protocol-common.txt.\n\n> > +General Request Processing\n> > +--------------------------\n> > +\n> > +Except where noted, all standard HTTP behavior SHOULD be assumed\n> > +by both client and server.  This includes (but is not necessarily\n> > +limited to):\n> > +\n> > +If there is no repository at $GIT_URL, the server MUST respond with\n> > +the '404 Not Found' HTTP status code.\n> \n> We may also want to add\n> \n>     If there is no object at $GIT_URL/some/path, the server MUST respond\n>     with the '404 Not Found' HTTP status code.\n> \n> to help dumb clients.\n\nProposed re-wording:\n\n  If there is no repository at $GIT_URL, or the resource pointed to by a\n  location containing $GIT_URL does not exist, the server MUST NOT respond\n  with '200 OK' response.  A server SHOULD respond with\n  '404 Not Found', '410 Gone', or any other suitable HTTP status code\n  which does not imply the resource exists as requested.\n\n(The 'valid info/refs response' part has been dropped.)\n\n> > +Dumb Clients\n> > +~~~~~~~~~~~~\n> > +\n> > +HTTP clients that only support the \"dumb\" protocol MUST discover\n> > +references by making a request for the special info/refs file of\n> > +the repository.\n> > +\n> > +Dumb HTTP clients MUST NOT include search/query parameters when\n> > +fetching the info/refs file.  (That is, '?' must not appear in the\n> > +requested URL.)\n> \n> It is unclear if '?' can be part of $GIT_URL. E.g.\n> \n>     $ wget http://example.xz/serve.cgi?path=git.git/info/refs\n>     $ git clone http://example.xz/serve.cgi?path=git.git\n> \n> It might be clearer to just say\n> \n>     Dumb HTTP clients MUST make a GET request against $GIT_URL/info/refs,\n>     without any search/query parameters.  I.e.\n> \n> \tC: GET $GIT_URL/info/refs HTTP/1.0\n> \n> to also exclude methods other than GET.\n\nDone.\n\n> > +\tC: GET $GIT_URL/info/refs HTTP/1.0\n> > +\n> > +\tS: 200 OK\n> > ...\n> > +When examining the response clients SHOULD only examine the HTTP\n> > +status code.  Valid responses are '200 OK', or '304 Not Modified'.\n> \n> Isn't 401 (\"Ah, I was given a wrong URL\") and 403 (\"Ok, I do not have an\n> access to this repository\") also valid?\n\nI think \"valid\" for the client means \"ok, continue processing\nnormally\".\n\n> > +The returned content is a UNIX formatted text file describing\n> > +each ref and its known value.  The file SHOULD be sorted by name\n> > +according to the C locale ordering.  The file SHOULD NOT include\n> > +the default ref named 'HEAD'.\n> \n> I know you said \"known\" to imply \"concurrent operations may change it\n> while the server is serving this client\", but it feels rather awkward.\n\nTODO\n\n> > +Smart Server Response\n> > +^^^^^^^^^^^^^^^^^^^^^\n> > +\n> > +Smart servers MUST respond with the smart server reply format.\n> > +If the server does not recognize the requested service name, or the\n> > +requested service name has been disabled by the server administrator,\n> > +the server MUST respond with the '403 Forbidden' HTTP status code.\n> \n> This is a bit confusing.\n> \n> If you as a server administrator want to disable the smart upload-pack for\n> one repository (but not for other repositories), you would not be able to\n> force smart clients to fall back to the dumb protocol by giving \"403\" for\n> that repository.\n> \n> Maybe in 2 years somebody smarter than us will have invented a more\n> efficient git-upload-pack-2 service, which is the only fetch protocol his\n> server supports other than dumb.  If your v1 smart client asks for the\n> original git-upload-pack service and gets a \"403\", you won't be able to\n> fall back to \"dumb\".\n> \n> The solution for such cases likely is to pretend as if you are a dumb\n> server for the smart request.  That unfortunately means that the first\n> sentence is misleading, and the second sentence is also an inappropriate\n> advice.\n\nProposed rewording:\n\n  If the server does not recognize the requested service name, or the\n  requested service name has been disabled by the server administrator,\n  the server MUST respond with the '403 Forbidden' HTTP status code.\n  \n  Otherwise, smart servers MUST respond with the smart server reply\n  format for the requested service name.\n\n> > +The Content-Type MUST be 'application/x-$servicename-advertisement'.\n> > +Clients SHOULD fall back to the dumb protocol if another content\n> > +type is returned.  When falling back to the dumb protocol clients\n> > +SHOULD NOT make an additional request to $GIT_URL/info/refs, but\n> > +instead SHOULD use the response already in hand.  Clients MUST NOT\n> > +continue if they do not support the dumb protocol.\n> \n> The part I commented on (the beginning of Smart Server Response) was\n> written as a generic description, not specific to git-upload-pack service,\n> and the beginning of this paragraph also pretends to be a generic\n> description, but it is misleading.  This is a specific instruction to the\n> clients that asked for git-upload-pack service and got a dumb server\n> response (if the above were talking about something other than upload-pack\n> service, there is no guarantee that \"response already in hand\" is useful\n> to talk to dumb servers).\n\nPrevious hunk should fix this.\n\n> > +\tref_list       = empty_list | populated_list\n> > +\n> > +\tempty_list     = PKT-LINE(id SP \"capabilities^{}\" NUL cap_list LF)\n> > +\n> > +\tnon_empty_list = PKT-LINE(id SP name NUL cap_list LF)\n> > +\t                 *ref_record\n>\n> [snip]\n> \n> Did you define what \"populated_list\" is?\n\nI think \"non_empty_list\" was meant.\n\nIdeally, ref advertisements should be in protocol-common.txt.\n\n> > +Smart Service git-upload-pack\n> > +------------------------------\n> > +This service reads from the remote repository.\n> \n> The wording \"remote repository\" felt confusing.  I know it is \"from the\n> repository served by the server\", but if it were named without\n> \"upload-pack\", I might have mistaken that you are allowing to proxy a\n> request to access a third-party repository by this server.  The same\n> comment applies to the git-receive-pack service.\n\nWould\n\n  This service reads from the repository pointed to by $GIT_URL.\n\nbe an improvement?\n\n> > +Capability include-tag\n> > +~~~~~~~~~~~~~~~~~~~~~~\n> > +\n> > +When packing an object that an annotated tag points at, include the\n> > +tag object too.  Clients can request this if they want to fetch\n> > +tags, but don't know which tags they will need until after they\n> > +receive the branch data.  By enabling include-tag an entire call\n> > +to upload-pack can be avoided.\n> > +\n> \n> I think you are avoiding an \"extra\" call; you would need one entire call\n> to upload-pack anyway for the primary transfer.\n\nDone.\n\n--\nCheers,\nRay Chuan\n"},{"id":"138870","messageId":"20100408021946.00007a27@unknown","threadId":"21164","inReplyTo":"7vskdss3ei.fsf@alter.siamese.dyndns.org","subject":"Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2010-04-07T18:19:46Z","receivedAt":"2010-04-07T18:19:46Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Hi,\n\n(I'm reviving this thread to complete the document. What I have right\nnow is available at my github repo; you can see it at\n\n  http://github.com/rctay/git/compare/git/next...feature/http-doc#files_bucket\n\n.\n\nAn inlined patch should be sent in soon.)\n\nOn Fri, 09 Oct 2009 13:44:53 -0700\nJunio C Hamano <gitster@pobox.com> wrote:\n\n> \"Shawn O. Pearce\" <spearce@spearce.org> writes:\n> > diff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\n> > new file mode 100644\n> > index 0000000..316d9b6\n> > --- /dev/null\n> > +++ b/Documentation/technical/http-protocol.txt\n> > @@ -0,0 +1,542 @@\n> > +HTTP transfer protocols\n> > +=======================\n> > ...\n> > +As a design feature smart clients can automatically upgrade \"dumb\"\n> > +protocol URLs to smart URLs.  This permits all users to have the\n> > +same published URL, and the peers automatically select the most\n> > +efficient transport available to them.\n> \n> The first sentence feels backwards although the conclusion in the second\n> sentence is true.  It is more like smart ones trying smart protocol first,\n> and downgrading to \"dumb\" after noticing that the server is not smart.\n\nI think Shawn is trying to describe this from the persepective of the\nclient implementation - a \"dumb\" url is first constructed, then\n\"upgraded\" to a \"smart\" one.\n\n> > +Authentication\n> > +--------------\n> > ...\n> > +Clients SHOULD support Basic authentication as described by RFC 2616.\n> > +Servers SHOULD support Basic authentication by relying upon the\n> > +HTTP server placed in front of the Git server software.\n> \n> It is perfectly fine to make it a requirement for a server to support the\n> Basic authentication, but should you make it a requirement that the\n> support is done by a specific implementation, i.e. \"by relying upon...\"?\n\nI think the term \"Server\" in this document is implied as an amalgam of\nthe HTTP server, and a CGI script/program (\"Git server software\"). I\nthink what Shawn meant was for Basic authentication to be implemented\nat the server layer, not in the CGI scripts/program.\n\n> > +Session State\n> > +-------------\n> > ...\n> > +retained and managed by the client process.  This permits simple\n> > +round-robin load-balancing on the server side, without needing to\n> > +worry about state mangement.\n> \n> s/mangement/management/;\n\nDone.\n\n> > +pkt-line Format\n> > +---------------\n> > ...\n> > +Examples (as C-style strings):\n> > +\n> > +  pkt-line          actual value\n> > +  ---------------------------------\n> > +  \"0006a\\n\"         \"a\\n\"\n> > +  \"0005a\"           \"a\"\n> > +  \"000bfoobar\\n\"    \"foobar\\n\"\n> > +  \"0004\"            \"\"\n> > +\n> > +A pkt-line with a length of 0 (\"0000\") is a special case and MUST\n> > +be treated as a message break or terminator in the payload.\n> \n> Isn't this \"MUST be\" wrong?\n> \n> It is not an advice to the implementors, but the protocol specification\n> itself defines what the flush packet means.  IOW, \"The author of this\n> specification, Shawn, MUST treat a flush packet as a message break or\n> terminator in the payload, when designing this protocol.\"\n\nThis section has been purged; we already have this in\nDocumentation/technical/protocol-common.txt.\n\n> > +General Request Processing\n> > +--------------------------\n> > +\n> > +Except where noted, all standard HTTP behavior SHOULD be assumed\n> > +by both client and server.  This includes (but is not necessarily\n> > +limited to):\n> > +\n> > +If there is no repository at $GIT_URL, the server MUST respond with\n> > +the '404 Not Found' HTTP status code.\n> \n> We may also want to add\n> \n>     If there is no object at $GIT_URL/some/path, the server MUST respond\n>     with the '404 Not Found' HTTP status code.\n> \n> to help dumb clients.\n\nProposed re-wording:\n\n  If there is no repository at $GIT_URL, or the resource pointed to by a\n  location containing $GIT_URL does not exist, the server MUST NOT respond\n  with '200 OK' response.  A server SHOULD respond with\n  '404 Not Found', '410 Gone', or any other suitable HTTP status code\n  which does not imply the resource exists as requested.\n\n(The 'valid info/refs response' part has been dropped.)\n\n> > +Dumb Clients\n> > +~~~~~~~~~~~~\n> > +\n> > +HTTP clients that only support the \"dumb\" protocol MUST discover\n> > +references by making a request for the special info/refs file of\n> > +the repository.\n> > +\n> > +Dumb HTTP clients MUST NOT include search/query parameters when\n> > +fetching the info/refs file.  (That is, '?' must not appear in the\n> > +requested URL.)\n> \n> It is unclear if '?' can be part of $GIT_URL. E.g.\n> \n>     $ wget http://example.xz/serve.cgi?path=git.git/info/refs\n>     $ git clone http://example.xz/serve.cgi?path=git.git\n> \n> It might be clearer to just say\n> \n>     Dumb HTTP clients MUST make a GET request against $GIT_URL/info/refs,\n>     without any search/query parameters.  I.e.\n> \n> \tC: GET $GIT_URL/info/refs HTTP/1.0\n> \n> to also exclude methods other than GET.\n\nDone.\n\n> > +\tC: GET $GIT_URL/info/refs HTTP/1.0\n> > +\n> > +\tS: 200 OK\n> > ...\n> > +When examining the response clients SHOULD only examine the HTTP\n> > +status code.  Valid responses are '200 OK', or '304 Not Modified'.\n> \n> Isn't 401 (\"Ah, I was given a wrong URL\") and 403 (\"Ok, I do not have an\n> access to this repository\") also valid?\n\nI think \"valid\" for the client means \"ok, continue processing\nnormally\".\n\n> > +The returned content is a UNIX formatted text file describing\n> > +each ref and its known value.  The file SHOULD be sorted by name\n> > +according to the C locale ordering.  The file SHOULD NOT include\n> > +the default ref named 'HEAD'.\n> \n> I know you said \"known\" to imply \"concurrent operations may change it\n> while the server is serving this client\", but it feels rather awkward.\n\nTODO\n\n> > +Smart Server Response\n> > +^^^^^^^^^^^^^^^^^^^^^\n> > +\n> > +Smart servers MUST respond with the smart server reply format.\n> > +If the server does not recognize the requested service name, or the\n> > +requested service name has been disabled by the server administrator,\n> > +the server MUST respond with the '403 Forbidden' HTTP status code.\n> \n> This is a bit confusing.\n> \n> If you as a server administrator want to disable the smart upload-pack for\n> one repository (but not for other repositories), you would not be able to\n> force smart clients to fall back to the dumb protocol by giving \"403\" for\n> that repository.\n> \n> Maybe in 2 years somebody smarter than us will have invented a more\n> efficient git-upload-pack-2 service, which is the only fetch protocol his\n> server supports other than dumb.  If your v1 smart client asks for the\n> original git-upload-pack service and gets a \"403\", you won't be able to\n> fall back to \"dumb\".\n> \n> The solution for such cases likely is to pretend as if you are a dumb\n> server for the smart request.  That unfortunately means that the first\n> sentence is misleading, and the second sentence is also an inappropriate\n> advice.\n\nProposed rewording:\n\n  If the server does not recognize the requested service name, or the\n  requested service name has been disabled by the server administrator,\n  the server MUST respond with the '403 Forbidden' HTTP status code.\n  \n  Otherwise, smart servers MUST respond with the smart server reply\n  format for the requested service name.\n\n> > +The Content-Type MUST be 'application/x-$servicename-advertisement'.\n> > +Clients SHOULD fall back to the dumb protocol if another content\n> > +type is returned.  When falling back to the dumb protocol clients\n> > +SHOULD NOT make an additional request to $GIT_URL/info/refs, but\n> > +instead SHOULD use the response already in hand.  Clients MUST NOT\n> > +continue if they do not support the dumb protocol.\n> \n> The part I commented on (the beginning of Smart Server Response) was\n> written as a generic description, not specific to git-upload-pack service,\n> and the beginning of this paragraph also pretends to be a generic\n> description, but it is misleading.  This is a specific instruction to the\n> clients that asked for git-upload-pack service and got a dumb server\n> response (if the above were talking about something other than upload-pack\n> service, there is no guarantee that \"response already in hand\" is useful\n> to talk to dumb servers).\n\nPrevious hunk should fix this.\n\n> > +\tref_list       = empty_list | populated_list\n> > +\n> > +\tempty_list     = PKT-LINE(id SP \"capabilities^{}\" NUL cap_list LF)\n> > +\n> > +\tnon_empty_list = PKT-LINE(id SP name NUL cap_list LF)\n> > +\t                 *ref_record\n>\n> [snip]\n> \n> Did you define what \"populated_list\" is?\n\nI think \"non_empty_list\" was meant.\n\nIdeally, ref advertisements should be in protocol-common.txt.\n\n> > +Smart Service git-upload-pack\n> > +------------------------------\n> > +This service reads from the remote repository.\n> \n> The wording \"remote repository\" felt confusing.  I know it is \"from the\n> repository served by the server\", but if it were named without\n> \"upload-pack\", I might have mistaken that you are allowing to proxy a\n> request to access a third-party repository by this server.  The same\n> comment applies to the git-receive-pack service.\n\nWould\n\n  This service reads from the repository pointed to by $GIT_URL.\n\nbe an improvement?\n\n> > +Capability include-tag\n> > +~~~~~~~~~~~~~~~~~~~~~~\n> > +\n> > +When packing an object that an annotated tag points at, include the\n> > +tag object too.  Clients can request this if they want to fetch\n> > +tags, but don't know which tags they will need until after they\n> > +receive the branch data.  By enabling include-tag an entire call\n> > +to upload-pack can be avoided.\n> > +\n> \n> I think you are avoiding an \"extra\" call; you would need one entire call\n> to upload-pack anyway for the primary transfer.\n\nDone.\n\n--\nCheers,\nRay Chuan\n"},{"id":"138879","messageId":"20100408031159.00006ec7@unknown","threadId":"21164","inReplyTo":"7vskdss3ei.fsf@alter.siamese.dyndns.org","subject":"(resend v2) Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2010-04-07T19:11:59Z","receivedAt":"2010-04-07T19:11:59Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"(sorry for the multiple copies - something wrong with my MUA. Had to\ngive it a kiss in the a** to get it working.)\n\n(v2 - added back headers. My apologies again.)\n\nHi,\n\n(I'm reviving this thread to complete the document. What I have right\nnow is available at my github repo; you can see it at\n\n  http://github.com/rctay/git/compare/git/next...feature/http-doc#files_bucket\n\n.\n\nAn inlined patch should be sent in soon.)\n\nOn Fri, 09 Oct 2009 13:44:53 -0700\nJunio C Hamano <gitster@pobox.com> wrote:\n\n> \"Shawn O. Pearce\" <spearce@spearce.org> writes:\n> > diff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\n> > new file mode 100644\n> > index 0000000..316d9b6\n> > --- /dev/null\n> > +++ b/Documentation/technical/http-protocol.txt\n> > @@ -0,0 +1,542 @@\n> > +HTTP transfer protocols\n> > +=======================\n> > ...\n> > +As a design feature smart clients can automatically upgrade \"dumb\"\n> > +protocol URLs to smart URLs.  This permits all users to have the\n> > +same published URL, and the peers automatically select the most\n> > +efficient transport available to them.\n>\n> The first sentence feels backwards although the conclusion in the second\n> sentence is true.  It is more like smart ones trying smart protocol first,\n> and downgrading to \"dumb\" after noticing that the server is not smart.\n\nI think Shawn is trying to describe this from the persepective of the\nclient implementation - a \"dumb\" url is first constructed, then\n\"upgraded\" to a \"smart\" one.\n\n> > +Authentication\n> > +--------------\n> > ...\n> > +Clients SHOULD support Basic authentication as described by RFC 2616.\n> > +Servers SHOULD support Basic authentication by relying upon the\n> > +HTTP server placed in front of the Git server software.\n>\n> It is perfectly fine to make it a requirement for a server to support the\n> Basic authentication, but should you make it a requirement that the\n> support is done by a specific implementation, i.e. \"by relying upon...\"?\n\nI think the term \"Server\" in this document is implied as an amalgam of\nthe HTTP server, and a CGI script/program (\"Git server software\"). I\nthink what Shawn meant was for Basic authentication to be implemented\nat the server layer, not in the CGI scripts/program.\n\n> > +Session State\n> > +-------------\n> > ...\n> > +retained and managed by the client process.  This permits simple\n> > +round-robin load-balancing on the server side, without needing to\n> > +worry about state mangement.\n>\n> s/mangement/management/;\n\nDone.\n\n> > +pkt-line Format\n> > +---------------\n> > ...\n> > +Examples (as C-style strings):\n> > +\n> > +  pkt-line          actual value\n> > +  ---------------------------------\n> > +  \"0006a\\n\"         \"a\\n\"\n> > +  \"0005a\"           \"a\"\n> > +  \"000bfoobar\\n\"    \"foobar\\n\"\n> > +  \"0004\"            \"\"\n> > +\n> > +A pkt-line with a length of 0 (\"0000\") is a special case and MUST\n> > +be treated as a message break or terminator in the payload.\n>\n> Isn't this \"MUST be\" wrong?\n>\n> It is not an advice to the implementors, but the protocol specification\n> itself defines what the flush packet means.  IOW, \"The author of this\n> specification, Shawn, MUST treat a flush packet as a message break or\n> terminator in the payload, when designing this protocol.\"\n\nThis section has been purged; we already have this in\nDocumentation/technical/protocol-common.txt.\n\n> > +General Request Processing\n> > +--------------------------\n> > +\n> > +Except where noted, all standard HTTP behavior SHOULD be assumed\n> > +by both client and server.  This includes (but is not necessarily\n> > +limited to):\n> > +\n> > +If there is no repository at $GIT_URL, the server MUST respond with\n> > +the '404 Not Found' HTTP status code.\n>\n> We may also want to add\n>\n>     If there is no object at $GIT_URL/some/path, the server MUST respond\n>     with the '404 Not Found' HTTP status code.\n>\n> to help dumb clients.\n\nProposed re-wording:\n\n  If there is no repository at $GIT_URL, or the resource pointed to by a\n  location containing $GIT_URL does not exist, the server MUST NOT respond\n  with '200 OK' response.  A server SHOULD respond with\n  '404 Not Found', '410 Gone', or any other suitable HTTP status code\n  which does not imply the resource exists as requested.\n\n(The 'valid info/refs response' part has been dropped.)\n\n> > +Dumb Clients\n> > +~~~~~~~~~~~~\n> > +\n> > +HTTP clients that only support the \"dumb\" protocol MUST discover\n> > +references by making a request for the special info/refs file of\n> > +the repository.\n> > +\n> > +Dumb HTTP clients MUST NOT include search/query parameters when\n> > +fetching the info/refs file.  (That is, '?' must not appear in the\n> > +requested URL.)\n>\n> It is unclear if '?' can be part of $GIT_URL. E.g.\n>\n>     $ wget http://example.xz/serve.cgi?path=git.git/info/refs\n>     $ git clone http://example.xz/serve.cgi?path=git.git\n>\n> It might be clearer to just say\n>\n>     Dumb HTTP clients MUST make a GET request against $GIT_URL/info/refs,\n>     without any search/query parameters.  I.e.\n>\n> \tC: GET $GIT_URL/info/refs HTTP/1.0\n>\n> to also exclude methods other than GET.\n\nDone.\n\n> > +\tC: GET $GIT_URL/info/refs HTTP/1.0\n> > +\n> > +\tS: 200 OK\n> > ...\n> > +When examining the response clients SHOULD only examine the HTTP\n> > +status code.  Valid responses are '200 OK', or '304 Not Modified'.\n>\n> Isn't 401 (\"Ah, I was given a wrong URL\") and 403 (\"Ok, I do not have an\n> access to this repository\") also valid?\n\nI think \"valid\" for the client means \"ok, continue processing\nnormally\".\n\n> > +The returned content is a UNIX formatted text file describing\n> > +each ref and its known value.  The file SHOULD be sorted by name\n> > +according to the C locale ordering.  The file SHOULD NOT include\n> > +the default ref named 'HEAD'.\n>\n> I know you said \"known\" to imply \"concurrent operations may change it\n> while the server is serving this client\", but it feels rather awkward.\n\nTODO\n\n> > +Smart Server Response\n> > +^^^^^^^^^^^^^^^^^^^^^\n> > +\n> > +Smart servers MUST respond with the smart server reply format.\n> > +If the server does not recognize the requested service name, or the\n> > +requested service name has been disabled by the server administrator,\n> > +the server MUST respond with the '403 Forbidden' HTTP status code.\n>\n> This is a bit confusing.\n>\n> If you as a server administrator want to disable the smart upload-pack for\n> one repository (but not for other repositories), you would not be able to\n> force smart clients to fall back to the dumb protocol by giving \"403\" for\n> that repository.\n>\n> Maybe in 2 years somebody smarter than us will have invented a more\n> efficient git-upload-pack-2 service, which is the only fetch protocol his\n> server supports other than dumb.  If your v1 smart client asks for the\n> original git-upload-pack service and gets a \"403\", you won't be able to\n> fall back to \"dumb\".\n>\n> The solution for such cases likely is to pretend as if you are a dumb\n> server for the smart request.  That unfortunately means that the first\n> sentence is misleading, and the second sentence is also an inappropriate\n> advice.\n\nProposed rewording:\n\n  If the server does not recognize the requested service name, or the\n  requested service name has been disabled by the server administrator,\n  the server MUST respond with the '403 Forbidden' HTTP status code.\n\n  Otherwise, smart servers MUST respond with the smart server reply\n  format for the requested service name.\n\n> > +The Content-Type MUST be 'application/x-$servicename-advertisement'.\n> > +Clients SHOULD fall back to the dumb protocol if another content\n> > +type is returned.  When falling back to the dumb protocol clients\n> > +SHOULD NOT make an additional request to $GIT_URL/info/refs, but\n> > +instead SHOULD use the response already in hand.  Clients MUST NOT\n> > +continue if they do not support the dumb protocol.\n>\n> The part I commented on (the beginning of Smart Server Response) was\n> written as a generic description, not specific to git-upload-pack service,\n> and the beginning of this paragraph also pretends to be a generic\n> description, but it is misleading.  This is a specific instruction to the\n> clients that asked for git-upload-pack service and got a dumb server\n> response (if the above were talking about something other than upload-pack\n> service, there is no guarantee that \"response already in hand\" is useful\n> to talk to dumb servers).\n\nPrevious hunk should fix this.\n\n> > +\tref_list       = empty_list | populated_list\n> > +\n> > +\tempty_list     = PKT-LINE(id SP \"capabilities^{}\" NUL cap_list LF)\n> > +\n> > +\tnon_empty_list = PKT-LINE(id SP name NUL cap_list LF)\n> > +\t                 *ref_record\n>\n> [snip]\n>\n> Did you define what \"populated_list\" is?\n\nI think \"non_empty_list\" was meant.\n\nIdeally, ref advertisements should be in protocol-common.txt.\n\n> > +Smart Service git-upload-pack\n> > +------------------------------\n> > +This service reads from the remote repository.\n>\n> The wording \"remote repository\" felt confusing.  I know it is \"from the\n> repository served by the server\", but if it were named without\n> \"upload-pack\", I might have mistaken that you are allowing to proxy a\n> request to access a third-party repository by this server.  The same\n> comment applies to the git-receive-pack service.\n\nWould\n\n  This service reads from the repository pointed to by $GIT_URL.\n\nbe an improvement?\n\n> > +Capability include-tag\n> > +~~~~~~~~~~~~~~~~~~~~~~\n> > +\n> > +When packing an object that an annotated tag points at, include the\n> > +tag object too.  Clients can request this if they want to fetch\n> > +tags, but don't know which tags they will need until after they\n> > +receive the branch data.  By enabling include-tag an entire call\n> > +to upload-pack can be avoided.\n> > +\n>\n> I think you are avoiding an \"extra\" call; you would need one entire call\n> to upload-pack anyway for the primary transfer.\n\nDone.\n\n--\nCheers,\nRay Chuan\n"},{"id":"138880","messageId":"20100408032442.992ab183.rctay89@gmail.com","threadId":"21164","inReplyTo":"7vskdss3ei.fsf@alter.siamese.dyndns.org","subject":"(resend v2) Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2010-04-07T19:24:42Z","receivedAt":"2010-04-07T19:24:42Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"(sorry for the multiple copies - something wrong with my MUA. Had to\ngive it a kiss in the a** to get it working.)\n\n(v2 - added back headers. My apologies again.)\n\nHi,\n\n(I'm reviving this thread to complete the document. What I have right\nnow is available at my github repo; you can see it at\n\n  http://github.com/rctay/git/compare/git/next...feature/http-doc#files_bucket\n\n.\n\nAn inlined patch should be sent in soon.)\n\nOn Fri, 09 Oct 2009 13:44:53 -0700\nJunio C Hamano <gitster@pobox.com> wrote:\n\n> \"Shawn O. Pearce\" <spearce@spearce.org> writes:\n> > diff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\n> > new file mode 100644\n> > index 0000000..316d9b6\n> > --- /dev/null\n> > +++ b/Documentation/technical/http-protocol.txt\n> > @@ -0,0 +1,542 @@\n> > +HTTP transfer protocols\n> > +=======================\n> > ...\n> > +As a design feature smart clients can automatically upgrade \"dumb\"\n> > +protocol URLs to smart URLs.  This permits all users to have the\n> > +same published URL, and the peers automatically select the most\n> > +efficient transport available to them.\n>\n> The first sentence feels backwards although the conclusion in the second\n> sentence is true.  It is more like smart ones trying smart protocol first,\n> and downgrading to \"dumb\" after noticing that the server is not smart.\n\nI think Shawn is trying to describe this from the persepective of the\nclient implementation - a \"dumb\" url is first constructed, then\n\"upgraded\" to a \"smart\" one.\n\n> > +Authentication\n> > +--------------\n> > ...\n> > +Clients SHOULD support Basic authentication as described by RFC 2616.\n> > +Servers SHOULD support Basic authentication by relying upon the\n> > +HTTP server placed in front of the Git server software.\n>\n> It is perfectly fine to make it a requirement for a server to support the\n> Basic authentication, but should you make it a requirement that the\n> support is done by a specific implementation, i.e. \"by relying upon...\"?\n\nI think the term \"Server\" in this document is implied as an amalgam of\nthe HTTP server, and a CGI script/program (\"Git server software\"). I\nthink what Shawn meant was for Basic authentication to be implemented\nat the server layer, not in the CGI scripts/program.\n\n> > +Session State\n> > +-------------\n> > ...\n> > +retained and managed by the client process.  This permits simple\n> > +round-robin load-balancing on the server side, without needing to\n> > +worry about state mangement.\n>\n> s/mangement/management/;\n\nDone.\n\n> > +pkt-line Format\n> > +---------------\n> > ...\n> > +Examples (as C-style strings):\n> > +\n> > +  pkt-line          actual value\n> > +  ---------------------------------\n> > +  \"0006a\\n\"         \"a\\n\"\n> > +  \"0005a\"           \"a\"\n> > +  \"000bfoobar\\n\"    \"foobar\\n\"\n> > +  \"0004\"            \"\"\n> > +\n> > +A pkt-line with a length of 0 (\"0000\") is a special case and MUST\n> > +be treated as a message break or terminator in the payload.\n>\n> Isn't this \"MUST be\" wrong?\n>\n> It is not an advice to the implementors, but the protocol specification\n> itself defines what the flush packet means.  IOW, \"The author of this\n> specification, Shawn, MUST treat a flush packet as a message break or\n> terminator in the payload, when designing this protocol.\"\n\nThis section has been purged; we already have this in\nDocumentation/technical/protocol-common.txt.\n\n> > +General Request Processing\n> > +--------------------------\n> > +\n> > +Except where noted, all standard HTTP behavior SHOULD be assumed\n> > +by both client and server.  This includes (but is not necessarily\n> > +limited to):\n> > +\n> > +If there is no repository at $GIT_URL, the server MUST respond with\n> > +the '404 Not Found' HTTP status code.\n>\n> We may also want to add\n>\n>     If there is no object at $GIT_URL/some/path, the server MUST respond\n>     with the '404 Not Found' HTTP status code.\n>\n> to help dumb clients.\n\nProposed re-wording:\n\n  If there is no repository at $GIT_URL, or the resource pointed to by a\n  location containing $GIT_URL does not exist, the server MUST NOT respond\n  with '200 OK' response.  A server SHOULD respond with\n  '404 Not Found', '410 Gone', or any other suitable HTTP status code\n  which does not imply the resource exists as requested.\n\n(The 'valid info/refs response' part has been dropped.)\n\n> > +Dumb Clients\n> > +~~~~~~~~~~~~\n> > +\n> > +HTTP clients that only support the \"dumb\" protocol MUST discover\n> > +references by making a request for the special info/refs file of\n> > +the repository.\n> > +\n> > +Dumb HTTP clients MUST NOT include search/query parameters when\n> > +fetching the info/refs file.  (That is, '?' must not appear in the\n> > +requested URL.)\n>\n> It is unclear if '?' can be part of $GIT_URL. E.g.\n>\n>     $ wget http://example.xz/serve.cgi?path=git.git/info/refs\n>     $ git clone http://example.xz/serve.cgi?path=git.git\n>\n> It might be clearer to just say\n>\n>     Dumb HTTP clients MUST make a GET request against $GIT_URL/info/refs,\n>     without any search/query parameters.  I.e.\n>\n> \tC: GET $GIT_URL/info/refs HTTP/1.0\n>\n> to also exclude methods other than GET.\n\nDone.\n\n> > +\tC: GET $GIT_URL/info/refs HTTP/1.0\n> > +\n> > +\tS: 200 OK\n> > ...\n> > +When examining the response clients SHOULD only examine the HTTP\n> > +status code.  Valid responses are '200 OK', or '304 Not Modified'.\n>\n> Isn't 401 (\"Ah, I was given a wrong URL\") and 403 (\"Ok, I do not have an\n> access to this repository\") also valid?\n\nI think \"valid\" for the client means \"ok, continue processing\nnormally\".\n\n> > +The returned content is a UNIX formatted text file describing\n> > +each ref and its known value.  The file SHOULD be sorted by name\n> > +according to the C locale ordering.  The file SHOULD NOT include\n> > +the default ref named 'HEAD'.\n>\n> I know you said \"known\" to imply \"concurrent operations may change it\n> while the server is serving this client\", but it feels rather awkward.\n\nTODO\n\n> > +Smart Server Response\n> > +^^^^^^^^^^^^^^^^^^^^^\n> > +\n> > +Smart servers MUST respond with the smart server reply format.\n> > +If the server does not recognize the requested service name, or the\n> > +requested service name has been disabled by the server administrator,\n> > +the server MUST respond with the '403 Forbidden' HTTP status code.\n>\n> This is a bit confusing.\n>\n> If you as a server administrator want to disable the smart upload-pack for\n> one repository (but not for other repositories), you would not be able to\n> force smart clients to fall back to the dumb protocol by giving \"403\" for\n> that repository.\n>\n> Maybe in 2 years somebody smarter than us will have invented a more\n> efficient git-upload-pack-2 service, which is the only fetch protocol his\n> server supports other than dumb.  If your v1 smart client asks for the\n> original git-upload-pack service and gets a \"403\", you won't be able to\n> fall back to \"dumb\".\n>\n> The solution for such cases likely is to pretend as if you are a dumb\n> server for the smart request.  That unfortunately means that the first\n> sentence is misleading, and the second sentence is also an inappropriate\n> advice.\n\nProposed rewording:\n\n  If the server does not recognize the requested service name, or the\n  requested service name has been disabled by the server administrator,\n  the server MUST respond with the '403 Forbidden' HTTP status code.\n\n  Otherwise, smart servers MUST respond with the smart server reply\n  format for the requested service name.\n\n> > +The Content-Type MUST be 'application/x-$servicename-advertisement'.\n> > +Clients SHOULD fall back to the dumb protocol if another content\n> > +type is returned.  When falling back to the dumb protocol clients\n> > +SHOULD NOT make an additional request to $GIT_URL/info/refs, but\n> > +instead SHOULD use the response already in hand.  Clients MUST NOT\n> > +continue if they do not support the dumb protocol.\n>\n> The part I commented on (the beginning of Smart Server Response) was\n> written as a generic description, not specific to git-upload-pack service,\n> and the beginning of this paragraph also pretends to be a generic\n> description, but it is misleading.  This is a specific instruction to the\n> clients that asked for git-upload-pack service and got a dumb server\n> response (if the above were talking about something other than upload-pack\n> service, there is no guarantee that \"response already in hand\" is useful\n> to talk to dumb servers).\n\nPrevious hunk should fix this.\n\n> > +\tref_list       = empty_list | populated_list\n> > +\n> > +\tempty_list     = PKT-LINE(id SP \"capabilities^{}\" NUL cap_list LF)\n> > +\n> > +\tnon_empty_list = PKT-LINE(id SP name NUL cap_list LF)\n> > +\t                 *ref_record\n>\n> [snip]\n>\n> Did you define what \"populated_list\" is?\n\nI think \"non_empty_list\" was meant.\n\nIdeally, ref advertisements should be in protocol-common.txt.\n\n> > +Smart Service git-upload-pack\n> > +------------------------------\n> > +This service reads from the remote repository.\n>\n> The wording \"remote repository\" felt confusing.  I know it is \"from the\n> repository served by the server\", but if it were named without\n> \"upload-pack\", I might have mistaken that you are allowing to proxy a\n> request to access a third-party repository by this server.  The same\n> comment applies to the git-receive-pack service.\n\nWould\n\n  This service reads from the repository pointed to by $GIT_URL.\n\nbe an improvement?\n\n> > +Capability include-tag\n> > +~~~~~~~~~~~~~~~~~~~~~~\n> > +\n> > +When packing an object that an annotated tag points at, include the\n> > +tag object too.  Clients can request this if they want to fetch\n> > +tags, but don't know which tags they will need until after they\n> > +receive the branch data.  By enabling include-tag an entire call\n> > +to upload-pack can be avoided.\n> > +\n>\n> I think you are avoiding an \"extra\" call; you would need one entire call\n> to upload-pack anyway for the primary transfer.\n\nDone.\n\n--\nCheers,\nRay Chuan\n"},{"id":"138885","messageId":"7v1verca7d.fsf@alter.siamese.dyndns.org","threadId":"21164","inReplyTo":"20100408031159.00006ec7@unknown","subject":"Re: (resend v2) Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-04-07T19:51:50Z","receivedAt":"2010-04-07T19:51:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Tay Ray Chuan <rctay89@gmail.com> writes:\n\n> (I'm reviving this thread to complete the document. What I have right\n> now is available at my github repo; you can see it at\n>\n>   http://github.com/rctay/git/compare/git/next...feature/http-doc#files_bucket\n\nI looked at the above page; it was quite readable.  You seem to have\npicked up Shawn's non-patch responses to reviews quite well.\n\nBy the way, aren't there a better way than visiting:\n\n    http://github.com/rctay/git/commits/feature/http-doc/Documentation/technical/http-protocol.txt\n\nand then repeat (click each commit, go back)\n\nto get a moral equivalent of \"git log -p feature/http-doc -- $that_path\"?\n"},{"id":"138908","messageId":"r2ibe6fef0d1004071847mc1b25e35q6e2db59f89ec15ee@mail.gmail.com","threadId":"21164","inReplyTo":"7v1verca7d.fsf@alter.siamese.dyndns.org","subject":"Re: (resend v2) Re: [RFC PATCH 1/4] Document the HTTP transport protocol","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2010-04-08T01:47:28Z","receivedAt":"2010-04-08T01:47:28Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Hi,\n\nOn Thu, Apr 8, 2010 at 3:51 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Tay Ray Chuan <rctay89@gmail.com> writes:\n>\n>> (I'm reviving this thread to complete the document. What I have right\n>> now is available at my github repo; you can see it at\n>>\n>>   http://github.com/rctay/git/compare/git/next...feature/http-doc#files_bucket\n>\n> I looked at the above page; it was quite readable.  You seem to have\n> picked up Shawn's non-patch responses to reviews quite well.\n\nThanks.\n\n> By the way, aren't there a better way than visiting:\n>\n>    http://github.com/rctay/git/commits/feature/http-doc/Documentation/technical/http-protocol.txt\n\nto view just the blob - yeah, but I'm so used to using github's\n\"Compare view\", it's the first thing I do.\n\n> and then repeat (click each commit, go back)\n>\n> to get a moral equivalent of \"git log -p feature/http-doc -- $that_path\"?\n\nThe Compare view let's you select a range of revisions, so it's not equivalent.\n\n-- \nCheers,\nRay Chuan\n"},{"id":"227332","messageId":"1378832878-12811-1-git-send-email-rctay89@gmail.com","threadId":"21164","inReplyTo":"1255065768-10428-2-git-send-email-spearce@spearce.org","subject":"[PATCH 00/14] document edits to original http protocol documentation","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2013-09-10T17:07:44Z","receivedAt":"2013-09-10T17:07:44Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"This patch series are the changes based on the discussion on Shawn's\noriginal text [1]. Some of them are minor, while some may potentially\nchange behaviour; see below for a classification of the changes.\nHopefully they can be examined by the git contributors here.\n\nAn earlier iteration of this patch series [2], including additional\nchanges by Nguyen [3], had been merged in 36d8020 (Merge branch\n'sp/doc-smart-http', Aug 30). Since that iteration, the changes have\nbeen corrected and consolidated. Effort has also been made to provide\nthe context for the changes; hopefully it helps with the review.\n\n[1] http://mid.gmane.org/<1255065768-10428-2-git-send-email-spearce@spearce.org>\n[2] https://github.com/rctay/git/blob/rc/http-doc/v1/p/Documentation/technical/http-protocol.txt\n[3] http://mid.gmane.org/<1377092713-25434-1-git-send-email-pclouds@gmail.com>\n\n(For convenience, a diff against 36d8020 is included at the end of this\nmessage; it is in word-diff form, hopefully for better clarity of the\nchanges.)\n\nGiven that an earlier iteration had already been merged, perhaps that\ncould be replaced with merge -Xtheirs (just throwing ideas, my git-fu is\nnot that strong). This would make the changes on the original RFC\navailable eg. via git-blame, which may be helpful for implementations\nmade based on the original RFC, especially since these \"early\"\nimplementations may now be in violation of the recently-included copy of\nthe spec.\n\nThe patches have been grouped based on their \"safeness\" (with regard to\npotentially changing the protocol spec), with a bias towards caution, as\nfollows:\n\nTrivial changes (eg formatting, style):\n  [PATCH 01/14] Document the HTTP transport protocol\n  [PATCH 02/14] normalize indentation with protcol-common.txt\n  [PATCH 03/14] capitalize key words according to RFC 2119\n  [PATCH 04/14] normalize rules with RFC 5234\n  [PATCH 05/14] drop rules, etc. common to the pack protocol\n  [PATCH 10/14] fix example request/responses\n  [PATCH 13/14] shift dumb server response details\n  \nRewords based on discussions that have been settled, or seem safe:\n  [PATCH 07/14] weaken specification over cookies for authentication\n  [PATCH 09/14] reduce ambiguity over '?' in $GIT_URL for dumb clients\n  [PATCH 11/14] be clearer in place of 'remote repository' phrase\n  \nPotentially behaviour-changes, may need of discussion:\n  [PATCH 06/14] reword behaviour on missing repository or objects\n  [PATCH 08/14] mention different variations around $GIT_URL\n  [PATCH 12/14] reduce confusion over smart server response behaviour\n  [PATCH 14/14] mention effect of \"allow-tip-sha1-in-want\" capability\n\nFull, ordered listing:\n  [PATCH 01/14] Document the HTTP transport protocol\n  [PATCH 02/14] normalize indentation with protcol-common.txt\n  [PATCH 03/14] capitalize key words according to RFC 2119\n  [PATCH 04/14] normalize rules with RFC 5234\n  [PATCH 05/14] drop rules, etc. common to the pack protocol\n  [PATCH 06/14] reword behaviour on missing repository or objects\n  [PATCH 07/14] weaken specification over cookies for authentication\n  [PATCH 08/14] mention different variations around $GIT_URL\n  [PATCH 09/14] reduce ambiguity over '?' in $GIT_URL for dumb clients\n  [PATCH 10/14] fix example request/responses\n  [PATCH 11/14] be clearer in place of 'remote repository' phrase\n  [PATCH 12/14] reduce confusion over smart server response behaviour\n  [PATCH 13/14] shift dumb server response details\n  [PATCH 14/14] mention effect of \"allow-tip-sha1-in-want\" capability\n\nThis patch series is queued at:\n\n  https://github.com/rctay/git/commits/rc/http-doc/v2/q\n\n-- \n1.8.4.rc4.527.g303b16c\n\noutput of\n\n  $ git diff -b --word-diff 36d8020 -- Documentation/technical/http-protocol.txt\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nindex a1173ee..acc68ac 100644\n--- a/Documentation/technical/http-protocol.txt\n+++ b/Documentation/technical/http-protocol.txt\n@@ -11,6 +11,10 @@ protocol URLs to smart URLs.  This permits all users to have the\nsame published URL, and the peers automatically select the most\nefficient transport available to them.\n\n{+The key words \"MUST\", \"MUST NOT\", \"REQUIRED\", \"SHALL\", \"SHALL+}\n{+NOT\", \"SHOULD\", \"SHOULD NOT\", \"RECOMMENDED\",  \"MAY\", and+}\n{+\"OPTIONAL\" in this document are to be interpreted as described in+}\n{+RFC 2119.+}\n\nURL Format\n----------\n@@ -33,16 +37,13 @@ An example of a dumb client requesting for a loose object:\n  $GIT_URL:     http://example.com:8080/git/repo.git\n  URL request:  http://example.com:8080/git/repo.git/objects/d0/49f6c27a2244e12041955e262a404c7faba355\n\nAn example of a smart request to a catch-all [-gateway:-]{+gateway (notice how the+}\n{+'service' parameter is passed with '&', since a '?' was detected in+}\n{+$GIT_URL):+}\n\n  $GIT_URL:     http://example.com/daemon.cgi?svc=git&q=\n  URL request:  http://example.com/daemon.cgi?svc=git&q=/info/refs&service=git-receive-pack\n\n[-An example of a request to a submodule:-]\n\n[-  $GIT_URL:     http://example.com/git/repo.git/path/submodule.git-]\n[-  URL request:  http://example.com/git/repo.git/path/submodule.git/info/refs-]\n\nClients MUST strip a trailing '/', if present, from the user supplied\n$GIT_URL string to prevent empty path tokens ('//') from appearing\nin any URL sent to a server.  Compatible clients MUST expand\n@@ -103,9 +104,10 @@ Except where noted, all standard HTTP behavior SHOULD be assumed\nby both client and server.  This includes (but is not necessarily\nlimited to):\n\nIf there is no repository at $GIT_URL, [-or-]{+the server MUST NOT respond with+}\n{+'200 OK' and a valid info/refs response.  Also, if+} the resource pointed\nto by a location matching $GIT_URL does not exist, the server MUST NOT\nrespond with '200 [-OK' response.-]{+OK'.+}  A server SHOULD respond with\n'404 Not Found', '410 Gone', or any other suitable HTTP status code\nwhich does not imply the resource exists as requested.\n\n@@ -114,12 +116,12 @@ permitted, the server MUST respond with the '403 Forbidden' HTTP\nstatus code.\n\nServers SHOULD support both HTTP 1.0 and HTTP 1.1.\nServers SHOULD support chunked encoding for both\nrequest and response bodies.\n\nClients SHOULD support both HTTP 1.0 and HTTP 1.1.\nClients SHOULD support chunked encoding for both\nrequest and response bodies.\n\nServers MAY return ETag and/or Last-Modified headers.\n\n@@ -149,40 +151,16 @@ references by making a request for the special info/refs file of\nthe repository.\n\nDumb HTTP clients MUST make a GET request to $GIT_URL/info/refs,\nwithout any search/query parameters.  {+E.g.+}\n\n   C: GET $GIT_URL/info/refs HTTP/1.0\n\n   S: 200 OK\n   S:\n   S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31\t[-refs/heads/maint-]{+refs/heads/maint\\n+}\n   S: d049f6c27a2244e12041955e262a404c7faba355\t[-refs/heads/master-]{+refs/heads/master\\n+}\n   S: 2cb58b79488a98d2721cea644875a8dd0026b115\t[-refs/tags/v1.0-]{+refs/tags/v1.0\\n+}\n   S: a3c2e2402b99163d1d59756e5f207ae21cccba4c\t[-refs/tags/v1.0^{}-]\n\n[-The Content-Type of the returned info/refs entity SHOULD be-]\n[-\"text/plain; charset=utf-8\", but MAY be any content type.-]\n[-Clients MUST NOT attempt to validate the returned Content-Type.-]\n[-Dumb servers MUST NOT return a return type starting with-]\n[-\"application/x-git-\".-]\n\n[-Cache-Control headers MAY be returned to disable caching of the-]\n[-returned entity.-]\n\n[-When examining the response clients SHOULD only examine the HTTP-]\n[-status code.  Valid responses are '200 OK', or '304 Not Modified'.-]\n\n[-The returned content is a UNIX formatted text file describing-]\n[-each ref and its known value.  The file SHOULD be sorted by name-]\n[-according to the C locale ordering.  The file SHOULD NOT include-]\n[-the default ref named 'HEAD'.-]\n\n[-  info_refs   =  *( ref_record )-]\n[-  ref_record  =  any_ref / peeled_ref-]\n\n[-  any_ref     =  obj-id HTAB refname LF-]\n[-  peeled_ref  =  obj-id HTAB refname LF-]\n[-\t\t obj-id HTAB refname \"^{}\" LF-]{+refs/tags/v1.0^{}\\n+}\n\nSmart Clients\n~~~~~~~~~~~~~\n@@ -196,15 +174,20 @@ The request MUST contain exactly one query parameter,\nname the client wishes to contact to complete the operation.\nThe request MUST NOT contain additional query parameters.\n\n{+TODO: \"exactly\" one query parameter may be too strict; see the catch-all+}\n{+gateway $GIT_URL for an example where more than one parameter is passed.+}\n{+In fact, the http client implementation in Git can handle similar+}\n{+$GIT_URLs, and thus may pass more than parameter to the server.+}\n\n   C: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0\n\n   dumb server reply:\n   S: 200 OK\n   S:\n   S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31\t[-refs/heads/maint-]{+refs/heads/maint\\n+}\n   S: d049f6c27a2244e12041955e262a404c7faba355\t[-refs/heads/master-]{+refs/heads/master\\n+}\n   S: 2cb58b79488a98d2721cea644875a8dd0026b115\t[-refs/tags/v1.0-]{+refs/tags/v1.0\\n+}\n   S: a3c2e2402b99163d1d59756e5f207ae21cccba4c\t[-refs/tags/v1.0^{}-]{+refs/tags/v1.0^{}\\n+}\n\n   smart server reply:\n   S: 200 OK\n@@ -216,13 +199,35 @@ The request MUST NOT contain additional query parameters.\n   S: 0042d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\\n\n   S: 003c2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0\\n\n   S: 003fa3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}\\n\n   {+S: 0000+}\n\nDumb Server Response\n^^^^^^^^^^^^^^^^^^^^\nDumb servers MUST respond with the dumb server reply format.\n\n[-See-]{+The Content-Type of+} the [-prior section under dumb clients for-]{+returned info/refs entity SHOULD be+}\n{+\"text/plain; charset=utf-8\", but MAY be any content type.+}\n{+Clients MUST NOT attempt to validate the returned Content-Type.+}\n{+Dumb servers MUST NOT return+} a [-more detailed-]\n[-description-]{+return type starting with+}\n{+\"application/x-git-\".+}\n\n{+Cache-Control headers MAY be returned to disable caching+} of the\n[-dumb server response.-]{+returned entity.+}\n\n{+When examining the response clients SHOULD only examine the HTTP+}\n{+status code.  Valid responses are '200 OK', or '304 Not Modified'.+}\n\n{+The returned content is a UNIX formatted text file describing+}\n{+each ref and its known value.  The file SHOULD be sorted by name+}\n{+according to the C locale ordering.  The file SHOULD NOT include+}\n{+the default ref named 'HEAD'.+}\n\n{+  info_refs        =  *( ref_record )+}\n{+  ref_record       =  any_ref / peeled_ref+}\n\n{+  any_ref          =  obj-id HTAB refname LF+}\n{+  peeled_ref       =  obj-id HTAB refname LF+}\n{+\t\t      obj-id HTAB refname \"^{}\" LF+}\n\nSmart Server Response\n^^^^^^^^^^^^^^^^^^^^^\n@@ -268,23 +273,7 @@ named 'HEAD' as the first ref.  The stream MUST include capability\ndeclarations behind a NUL on the first ref.\n\n  smart_reply      =  PKT-LINE(\"# service=$servicename\" LF)\n\t\t      [-ref_list-]\n[-\t\t     \"0000\"-]\n[-  ref_list        =  empty_list / non_empty_list-]\n\n[-  empty_list      =  PKT-LINE(zero-id SP \"capabilities^{}\" NUL cap-list LF)-]\n\n[-  non_empty_list  =  PKT-LINE(obj-id SP name NUL cap_list LF)-]\n[-\t\t     *ref_record-]\n\n[-  cap-list        =  capability *(SP capability)-]\n[-  capability      =  1*(LC_ALPHA / DIGIT / \"-\" / \"_\")-]\n[-  LC_ALPHA        =  %x61-7A-]\n\n[-  ref_record      =  any_ref / peeled_ref-]\n[-  any_ref         =  PKT-LINE(obj-id SP name LF)-]\n[-  peeled_ref      =  PKT-LINE(obj-id SP name LF)-]\n[-\t\t     PKT-LINE(obj-id SP name \"^{}\" LF-]{+advertised-refs+}\n\nSmart Service git-upload-pack\n------------------------------\n@@ -394,7 +383,7 @@ The computation to select the minimal pack proceeds as follows\n     emptied C_PENDING it SHOULD include a \"done\" command to let\n     the server know it won't proceed:\n\n   C: [-0009done-]{+0009done\\n+}\n\n  (s) Parse the git-upload-pack request:\n\n@@ -450,7 +439,7 @@ TODO: Document parsing response\n\nSmart Service git-receive-pack\n------------------------------\nThis service [-reads from-]{+modifies+} the repository pointed to by $GIT_URL.\n\nClients MUST first perform ref discovery with\n'$GIT_URL/info/refs?service=git-receive-pack'.\n@@ -458,7 +447,7 @@ Clients MUST first perform ref discovery with\n   C: POST $GIT_URL/git-receive-pack HTTP/1.0\n   C: Content-Type: application/x-git-receive-pack-request\n   C:\n   C: ....0a53e9ddeaddad63ad106860237bbf53411d11a7 441b40d833fdfa93eb2908e52742248faf0ee993 [-refs/heads/maint\\0 report-status-]{+refs/heads/maint\\0report-status+}\n   C: 0000\n   C: PACK....\n\n@@ -487,9 +476,9 @@ the id obtained through ref discovery as old_id.\n  cap_list         =  *(SP capability) SP\n\n  command          =  create / delete / update\n  create           =  zero-id SP new_id SP [-name-]{+refname+}\n  delete           =  old_id SP zero-id SP [-name-]{+refname+}\n  update           =  old_id SP new_id SP [-name-]{+refname+}\n\nTODO: Document this further.\n\n@@ -498,6 +487,9 @@ References\n----------\n\nlink:http://www.ietf.org/rfc/rfc1738.txt[RFC 1738: Uniform Resource Locators (URL)]\n{+link:http://www.ietf.org/rfc/rfc2119.txt[RFC 2119: Key words for use in RFCs to Indicate Requirement Levels]+}\nlink:http://www.ietf.org/rfc/rfc2616.txt[RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1]\nlink:technical/pack-protocol.txt\n{+link:technical/protocol-common.txt+}\nlink:technical/protocol-capabilities.txt\n"},{"id":"227343","messageId":"1378832878-12811-2-git-send-email-rctay89@gmail.com","threadId":"21164","inReplyTo":"1378832878-12811-1-git-send-email-rctay89@gmail.com","subject":"[PATCH 01/14] Document the HTTP transport protocol","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2013-09-10T17:07:45Z","receivedAt":"2013-09-10T17:07:45Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"From: \"Shawn O. Pearce\" <spearce@spearce.org>\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n--\n\nThis is the original\n\n  <1255065768-10428-2-git-send-email-spearce@spearce.org>\n\nwith some minor changes, as follows:\n - fix mis-spelling 'paramterized'\n - fix mis-spelling 'mangement' (spotted by Junio)\n - fix missing ABNF reference for smart replies (spotted by Sverre, Junio)\n---\n Documentation/technical/http-protocol.txt | 542 ++++++++++++++++++++++++++++++\n 1 file changed, 542 insertions(+)\n create mode 100644 Documentation/technical/http-protocol.txt\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nnew file mode 100644\nindex 0000000..0a2a53d\n--- /dev/null\n+++ b/Documentation/technical/http-protocol.txt\n@@ -0,0 +1,542 @@\n+HTTP transfer protocols\n+=======================\n+\n+Git supports two HTTP based transfer protocols.  A \"dumb\" protocol\n+which requires only a standard HTTP server on the server end of the\n+connection, and a \"smart\" protocol which requires a Git aware CGI\n+(or server module).  This document describes both protocols.\n+\n+As a design feature smart clients can automatically upgrade \"dumb\"\n+protocol URLs to smart URLs.  This permits all users to have the\n+same published URL, and the peers automatically select the most\n+efficient transport available to them.\n+\n+\n+URL Format\n+----------\n+\n+URLs for Git repositories accessed by HTTP use the standard HTTP\n+URL syntax documented by RFC 1738, so they are of the form:\n+\n+  http://<host>:<port>/<path>\n+\n+Within this documentation the placeholder $GIT_URL will stand for\n+the http:// repository URL entered by the end-user.\n+\n+Both the \"smart\" and \"dumb\" HTTP protocols used by Git operate\n+by appending additional path components onto the end of the user\n+supplied $GIT_URL string.\n+\n+Clients MUST strip a trailing '/', if present, from the user supplied\n+$GIT_URL string to prevent empty path tokens ('//') from appearing\n+in any URL sent to a server.  Compatible clients must expand\n+'$GIT_URL/info/refs' as 'foo/info/refs' and not 'foo//info/refs'.\n+\n+\n+Authentication\n+--------------\n+\n+Standard HTTP authentication is used if authentication is required\n+to access a repository, and MAY be configured and enforced by the\n+HTTP server software.\n+\n+Because Git repositories are accessed by standard path components\n+server administrators MAY use directory based permissions within\n+their HTTP server to control repository access.\n+\n+Clients SHOULD support Basic authentication as described by RFC 2616.\n+Servers SHOULD support Basic authentication by relying upon the\n+HTTP server placed in front of the Git server software.\n+\n+Servers MUST NOT require HTTP cookies for the purposes of\n+authentication or access control.\n+\n+Clients and servers MAY support other common forms of HTTP based\n+authentication, such as Digest authentication.\n+\n+\n+SSL\n+---\n+\n+Clients and servers SHOULD support SSL, particularly to protect\n+passwords when relying on Basic HTTP authentication.\n+\n+\n+Session State\n+-------------\n+\n+The Git over HTTP protocol (much like HTTP itself) is stateless\n+from the perspective of the HTTP server side.  All state must be\n+retained and managed by the client process.  This permits simple\n+round-robin load-balancing on the server side, without needing to\n+worry about state management.\n+\n+Clients MUST NOT require state management on the server side in\n+order to function correctly.\n+\n+Servers MUST NOT require HTTP cookies in order to function correctly.\n+Clients MAY store and forward HTTP cookies during request processing\n+as described by RFC 2616 (HTTP/1.1).  Servers SHOULD ignore any\n+cookies sent by a client.\n+\n+\n+pkt-line Format\n+---------------\n+\n+Much (but not all) of the payload is described around pkt-lines.\n+\n+A pkt-line is a variable length binary string.  The first four bytes\n+of the line indicates the total length of the line, in hexadecimal.\n+The total length includes the 4 bytes used to denote the length.\n+A line SHOULD BE terminated by an LF, which if present MUST be\n+included in the total length.\n+\n+A pkt-line MAY contain binary data, so implementors MUST ensure all\n+pkt-line parsing/formatting routines are 8-bit clean.  The maximum\n+length of a pkt-line's data is 65532 bytes (65536 - 4).\n+\n+Examples (as C-style strings):\n+\n+  pkt-line          actual value\n+  ---------------------------------\n+  \"0006a\\n\"         \"a\\n\"\n+  \"0005a\"           \"a\"\n+  \"000bfoobar\\n\"    \"foobar\\n\"\n+  \"0004\"            \"\"\n+\n+A pkt-line with a length of 0 (\"0000\") is a special case and MUST\n+be treated as a message break or terminator in the payload.\n+\n+\n+General Request Processing\n+--------------------------\n+\n+Except where noted, all standard HTTP behavior SHOULD be assumed\n+by both client and server.  This includes (but is not necessarily\n+limited to):\n+\n+If there is no repository at $GIT_URL, the server MUST respond with\n+the '404 Not Found' HTTP status code.\n+\n+If there is a repository at $GIT_URL, but access is not currently\n+permitted, the server MUST respond with the '403 Forbidden' HTTP\n+status code.\n+\n+Servers SHOULD support both HTTP 1.0 and HTTP 1.1.\n+Servers SHOULD support chunked encoding for both\n+request and response bodies.\n+\n+Clients SHOULD support both HTTP 1.0 and HTTP 1.1.\n+Clients SHOULD support chunked encoding for both\n+request and response bodies.\n+\n+Servers MAY return ETag and/or Last-Modified headers.\n+\n+Clients MAY revalidate cached entities by including If-Modified-Since\n+and/or If-None-Match request headers.\n+\n+Servers MAY return '304 Not Modified' if the relevant headers appear\n+in the request and the entity has not changed.  Clients MUST treat\n+'304 Not Modified' identical to '200 OK' by reusing the cached entity.\n+\n+Clients MAY reuse a cached entity without revalidation if the\n+Cache-Control and/or Expires header permits caching.  Clients and\n+servers MUST follow RFC 2616 for cache controls.\n+\n+\n+Discovering References\n+----------------------\n+\n+All HTTP clients MUST begin either a fetch or a push exchange by\n+discovering the references available on the remote repository.\n+\n+Dumb Clients\n+~~~~~~~~~~~~\n+\n+HTTP clients that only support the \"dumb\" protocol MUST discover\n+references by making a request for the special info/refs file of\n+the repository.\n+\n+Dumb HTTP clients MUST NOT include search/query parameters when\n+fetching the info/refs file.  (That is, '?' must not appear in the\n+requested URL.)\n+\n+\tC: GET $GIT_URL/info/refs HTTP/1.0\n+\n+\tS: 200 OK\n+\tS:\n+\tS: 95dcfa3633004da0049d3d0fa03f80589cbcaf31\trefs/heads/maint\n+\tS: d049f6c27a2244e12041955e262a404c7faba355\trefs/heads/master\n+\tS: 2cb58b79488a98d2721cea644875a8dd0026b115\trefs/tags/v1.0\n+\tS: a3c2e2402b99163d1d59756e5f207ae21cccba4c\trefs/tags/v1.0^{}\n+\n+The Content-Type of the returned info/refs entity SHOULD be\n+\"text/plain; charset=utf-8\", but MAY be any content type.\n+Clients MUST NOT attempt to validate the returned Content-Type.\n+Dumb servers MUST NOT return a return type starting with\n+\"application/x-git-\".\n+\n+Cache-Control headers MAY be returned to disable caching of the\n+returned entity.\n+\n+When examining the response clients SHOULD only examine the HTTP\n+status code.  Valid responses are '200 OK', or '304 Not Modified'.\n+\n+The returned content is a UNIX formatted text file describing\n+each ref and its known value.  The file SHOULD be sorted by name\n+according to the C locale ordering.  The file SHOULD NOT include\n+the default ref named 'HEAD'.\n+\n+\tinfo_refs     = *( ref_record )\n+\tref_record    = any_ref | peeled_ref\n+\n+\tany_ref       = id HT name LF\n+\tpeeled_ref    = id HT name LF\n+\t                id HT name \"^{}\" LF\n+\tid            = 40*HEX\n+\n+\tHEX           = \"0\"..\"9\" | \"a\"..\"f\"\n+\tLF            = <US-ASCII LF, linefeed (10)>\n+\tHT            = <US-ASCII HT, horizontal-tab (9)>\n+\n+Smart Clients\n+~~~~~~~~~~~~~\n+\n+HTTP clients that support the \"smart\" protocol (or both the\n+\"smart\" and \"dumb\" protocols) MUST discover references by making\n+a parameterized request for the info/refs file of the repository.\n+\n+The request MUST contain exactly one query parameter,\n+'service=$servicename', where $servicename MUST be the service\n+name the client wishes to contact to complete the operation.\n+The request MUST NOT contain additional query parameters.\n+\n+\tC: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0\n+\n+\tdumb server reply:\n+\tS: 200 OK\n+\tS:\n+\tS: 95dcfa3633004da0049d3d0fa03f80589cbcaf31\trefs/heads/maint\n+\tS: d049f6c27a2244e12041955e262a404c7faba355\trefs/heads/master\n+\tS: 2cb58b79488a98d2721cea644875a8dd0026b115\trefs/tags/v1.0\n+\tS: a3c2e2402b99163d1d59756e5f207ae21cccba4c\trefs/tags/v1.0^{}\n+\n+\tsmart server reply:\n+\tS: 200 OK\n+\tS: Content-Type: application/x-git-upload-pack-advertisement\n+\tS: Cache-Control: no-cache\n+\tS:\n+\tS: ....# service=git-upload-pack\n+\tS: ....95dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint\\0 multi_ack\n+\tS: ....d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\n+\tS: ....2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0\n+\tS: ....a3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}\n+\n+Dumb Server Response\n+^^^^^^^^^^^^^^^^^^^^\n+Dumb servers MUST respond with the dumb server reply format.\n+\n+See the prior section under dumb clients for a more detailed\n+description of the dumb server response.\n+\n+Smart Server Response\n+^^^^^^^^^^^^^^^^^^^^^\n+Smart servers MUST respond with the smart server reply format.\n+\n+If the server does not recognize the requested service name, or the\n+requested service name has been disabled by the server administrator,\n+the server MUST respond with the '403 Forbidden' HTTP status code.\n+\n+Cache-Control headers SHOULD be used to disable caching of the\n+returned entity.\n+\n+The Content-Type MUST be 'application/x-$servicename-advertisement'.\n+Clients SHOULD fall back to the dumb protocol if another content\n+type is returned.  When falling back to the dumb protocol clients\n+SHOULD NOT make an additional request to $GIT_URL/info/refs, but\n+instead SHOULD use the response already in hand.  Clients MUST NOT\n+continue if they do not support the dumb protocol.\n+\n+Clients MUST validate the status code is either '200 OK' or\n+'304 Not Modified'.\n+\n+Clients MUST validate the first five bytes of the response entity\n+matches the regex \"^[0-9a-f]{4}#\".  If this test fails, clients\n+MUST NOT continue.\n+\n+Clients MUST parse the entire response as a sequence of pkt-line\n+records.\n+\n+Clients MUST verify the first pkt-line is \"# service=$servicename\".\n+Servers MUST set $servicename to be the request parameter value.\n+Servers SHOULD include an LF at the end of this line.\n+Clients MUST ignore an LF at the end of the line.\n+\n+Servers MUST terminate the response with the magic \"0000\" end\n+pkt-line marker.\n+\n+The returned response is a pkt-line stream describing each ref and\n+its known value.  The stream SHOULD be sorted by name according to\n+the C locale ordering.  The stream SHOULD include the default ref\n+named 'HEAD' as the first ref.  The stream MUST include capability\n+declarations behind a NUL on the first ref.\n+\n+\tsmart_reply    = PKT-LINE(\"# service=$servicename\" LF)\n+\t                 ref_list\n+\t                 \"0000\"\n+\tref_list       = empty_list | non_empty_list\n+\n+\tempty_list     = PKT-LINE(id SP \"capabilities^{}\" NUL cap_list LF)\n+\n+\tnon_empty_list = PKT-LINE(id SP name NUL cap_list LF)\n+\t                 *ref_record\n+\n+\tcap_list      = *(SP capability) SP\n+\tref_record    = any_ref | peeled_ref\n+\n+\tany_ref       = PKT-LINE(id SP name LF)\n+\tpeeled_ref    = PKT-LINE(id SP name LF)\n+\t                PKT-LINE(id SP name \"^{}\" LF\n+\tid            = 40*HEX\n+\n+\tHEX           = \"0\"..\"9\" | \"a\"..\"f\"\n+\tNL            = <US-ASCII NUL, null (0)>\n+\tLF            = <US-ASCII LF,  linefeed (10)>\n+\tSP            = <US-ASCII SP,  horizontal-tab (9)>\n+\n+\n+Smart Service git-upload-pack\n+------------------------------\n+This service reads from the remote repository.\n+\n+Clients MUST first perform ref discovery with\n+'$GIT_URL/info/refs?service=git-upload-pack'.\n+\n+\tC: POST $GIT_URL/git-upload-pack HTTP/1.0\n+\tC: Content-Type: application/x-git-upload-pack-request\n+\tC:\n+\tC: ....want 0a53e9ddeaddad63ad106860237bbf53411d11a7\n+\tC: ....have 441b40d833fdfa93eb2908e52742248faf0ee993\n+\tC: 0000\n+\n+\tS: 200 OK\n+\tS: Content-Type: application/x-git-upload-pack-result\n+\tS: Cache-Control: no-cache\n+\tS:\n+\tS: ....ACK %s, continue\n+\tS: ....NAK\n+\n+Clients MUST NOT reuse or revalidate a cached reponse.\n+Servers MUST include sufficient Cache-Control headers\n+to prevent caching of the response.\n+\n+Servers SHOULD support all capabilities defined here.\n+\n+Clients MUST send at least one 'want' command in the request body.\n+Clients MUST NOT reference an id in a 'want' command which did not\n+appear in the response obtained through ref discovery.\n+\n+\tcompute_request   = want_list\n+\t                    have_list\n+\t                    request_end\n+\trequest_end       = \"0000\" | \"done\"\n+\n+\twant_list         = PKT-LINE(want NUL cap_list LF)\n+\t                    *(want_pkt)\n+\twant_pkt          = PKT-LINE(want LF)\n+\twant              = \"want\" SP id\n+\tcap_list          = *(SP capability) SP\n+\n+\thave_list         = *PKT-LINE(\"have\" SP id LF)\n+\n+\tcommand           = create | delete | update\n+\tcreate            = 40*\"0\" SP new_id SP name\n+\tdelete            = old_id SP 40*\"0\" SP name\n+\tupdate            = old_id SP new_id SP name\n+\n+TODO: Document this further.\n+TODO: Don't use uppercase for variable names below.\n+\n+Capability include-tag\n+~~~~~~~~~~~~~~~~~~~~~~\n+\n+When packing an object that an annotated tag points at, include the\n+tag object too.  Clients can request this if they want to fetch\n+tags, but don't know which tags they will need until after they\n+receive the branch data.  By enabling include-tag an entire call\n+to upload-pack can be avoided.\n+\n+Capability thin-pack\n+~~~~~~~~~~~~~~~~~~~~\n+\n+When packing a deltified object the base is not included if the base\n+is reachable from an object listed in the COMMON set by the client.\n+This reduces the bandwidth required to transfer, but it does slightly\n+increase processing time for the client to save the pack to disk.\n+\n+The Negotiation Algorithm\n+~~~~~~~~~~~~~~~~~~~~~~~~~\n+The computation to select the minimal pack proceeds as follows\n+(c = client, s = server):\n+\n+ init step:\n+ (c) Use ref discovery to obtain the advertised refs.\n+ (c) Place any object seen into set ADVERTISED.\n+\n+ (c) Build an empty set, COMMON, to hold the objects that are later\n+     determined to be on both ends.\n+ (c) Build a set, WANT, of the objects from ADVERTISED the client\n+     wants to fetch, based on what it saw during ref discovery.\n+\n+ (c) Start a queue, C_PENDING, ordered by commit time (popping newest\n+     first).  Add all client refs.  When a commit is popped from\n+     the queue its parents should be automatically inserted back.\n+     Commits MUST only enter the queue once.\n+\n+ one compute step:\n+ (c) Send one $GIT_URL/git-upload-pack request:\n+\n+\tC: 0032want <WANT #1>...............................\n+\tC: 0032want <WANT #2>...............................\n+\t....\n+\tC: 0032have <COMMON #1>.............................\n+\tC: 0032have <COMMON #2>.............................\n+\t....\n+\tC: 0032have <HAVE #1>...............................\n+\tC: 0032have <HAVE #2>...............................\n+\t....\n+\tC: 0000\n+\n+     The stream is organized into \"commands\", with each command\n+     appearing by itself in a pkt-line.  Within a command line\n+     the text leading up to the first space is the command name,\n+     and the remainder of the line to the first LF is the value.\n+     Command lines are terminated with an LF as the last byte of\n+     the pkt-line value.\n+\n+     Commands MUST appear in the following order, if they appear\n+     at all in the request stream:\n+\n+       * want\n+       * have\n+\n+     The stream is terminated by a pkt-line flush (\"0000\").\n+\n+     A single \"want\" or \"have\" command MUST have one hex formatted\n+     SHA-1 as its value.  Multiple SHA-1s MUST be sent by sending\n+     multiple commands.\n+\n+     The HAVE list is created by popping the first 32 commits\n+     from C_PENDING.  Less can be supplied if C_PENDING empties.\n+\n+     If the client has sent 256 HAVE commits and has not yet\n+     received one of those back from S_COMMON, or the client has\n+     emptied C_PENDING it should include a \"done\" command to let\n+     the server know it won't proceed:\n+\n+\tC: 0009done\n+\n+  (s) Parse the git-upload-pack request:\n+\n+      Verify all objects in WANT are directly reachable from refs.\n+\n+\t  The server MAY walk backwards through history or through\n+      the reflog to permit slightly stale requests.\n+\n+      If no WANT objects are received, send an error:\n+\n+TODO: Define error if no want lines are requested.\n+\n+      If any WANT object is not reachable, send an error:\n+\n+TODO: Define error if an invalid want is requested.\n+\n+     Create an empty list, S_COMMON.\n+\n+     If 'have' was sent:\n+\n+     Loop through the objects in the order supplied by the client.\n+     For each object, if the server has the object reachable from\n+     a ref, add it to S_COMMON.  If a commit is added to S_COMMON,\n+     do not add any ancestors, even if they also appear in HAVE.\n+\n+  (s) Send the git-upload-pack response:\n+\n+     If the server has found a closed set of objects to pack or the\n+     request ends with \"done\", it replies with the pack.\n+\n+TODO: Document the pack based response\n+\tS: PACK...\n+\n+     The returned stream is the side-band-64k protocol supported\n+     by the git-upload-pack service, and the pack is embedded into\n+     stream 1.  Progress messages from the server side may appear\n+     in stream 2.\n+\n+     Here a \"closed set of objects\" is defined to have at least\n+     one path from every WANT to at least one COMMON object.\n+\n+     If the server needs more information, it replies with a\n+     status continue response:\n+\n+TODO: Document the non-pack response\n+\n+  (c) Parse the upload-pack response:\n+\n+TODO: Document parsing response\n+\n+      Do another compute step.\n+\n+\n+Smart Service git-receive-pack\n+------------------------------\n+This service modifies the remote repository.\n+\n+Clients MUST first perform ref discovery with\n+'$GIT_URL/info/refs?service=git-receive-pack'.\n+\n+\tC: POST $GIT_URL/git-receive-pack HTTP/1.0\n+\tC: Content-Type: application/x-git-receive-pack-request\n+\tC:\n+\tC: ....0a53e9ddeaddad63ad106860237bbf53411d11a7 441b40d833fdfa93eb2908e52742248faf0ee993 refs/heads/maint\\0 report-status\n+\tC: 0000\n+\tC: PACK....\n+\n+\tS: 200 OK\n+\tS: Content-Type: application/x-git-receive-pack-result\n+\tS: Cache-Control: no-cache\n+\tS:\n+\tS: ....\n+\n+Clients MUST NOT reuse or revalidate a cached reponse.\n+Servers MUST include sufficient Cache-Control headers\n+to prevent caching of the response.\n+\n+Servers SHOULD support all capabilities defined here.\n+\n+Clients MUST send at least one command in the request body.\n+Within the command portion of the request body clients SHOULD send\n+the id obtained through ref discovery as old_id.\n+\n+\tupdate_request    = command_list\n+\t                    \"PACK\" <binary data>\n+\n+\tcommand_list      = PKT-LINE(command NUL cap_list LF)\n+\t                    *(command_pkt)\n+\tcommand_pkt       = PKT-LINE(command LF)\n+\tcap_list          = *(SP capability) SP\n+\n+\tcommand           = create | delete | update\n+\tcreate            = 40*\"0\" SP new_id SP name\n+\tdelete            = old_id SP 40*\"0\" SP name\n+\tupdate            = old_id SP new_id SP name\n+\n+TODO: Document this further.\n+\n+\n+References\n+----------\n+\n+link:http://www.ietf.org/rfc/rfc1738.txt[RFC 1738: Uniform Resource Locators (URL)]\n+link:http://www.ietf.org/rfc/rfc2616.txt[RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1]\n+\n-- \n1.8.4.rc4.527.g303b16c\n"},{"id":"227346","messageId":"1378832878-12811-3-git-send-email-rctay89@gmail.com","threadId":"21164","inReplyTo":"1378832878-12811-2-git-send-email-rctay89@gmail.com","subject":"[PATCH 02/14] normalize indentation with protcol-common.txt","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2013-09-10T17:07:46Z","receivedAt":"2013-09-10T17:07:46Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Indent client/server query examples with 3 spaces.\n\nIndent ABNF rules with 2 spaces.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n--\n\nThis is in its own patch to minimize noise in diffs.\n---\n Documentation/technical/http-protocol.txt | 226 +++++++++++++++---------------\n 1 file changed, 113 insertions(+), 113 deletions(-)\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nindex 0a2a53d..70a1648 100644\n--- a/Documentation/technical/http-protocol.txt\n+++ b/Documentation/technical/http-protocol.txt\n@@ -161,14 +161,14 @@ Dumb HTTP clients MUST NOT include search/query parameters when\n fetching the info/refs file.  (That is, '?' must not appear in the\n requested URL.)\n \n-\tC: GET $GIT_URL/info/refs HTTP/1.0\n+   C: GET $GIT_URL/info/refs HTTP/1.0\n \n-\tS: 200 OK\n-\tS:\n-\tS: 95dcfa3633004da0049d3d0fa03f80589cbcaf31\trefs/heads/maint\n-\tS: d049f6c27a2244e12041955e262a404c7faba355\trefs/heads/master\n-\tS: 2cb58b79488a98d2721cea644875a8dd0026b115\trefs/tags/v1.0\n-\tS: a3c2e2402b99163d1d59756e5f207ae21cccba4c\trefs/tags/v1.0^{}\n+   S: 200 OK\n+   S:\n+   S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31\trefs/heads/maint\n+   S: d049f6c27a2244e12041955e262a404c7faba355\trefs/heads/master\n+   S: 2cb58b79488a98d2721cea644875a8dd0026b115\trefs/tags/v1.0\n+   S: a3c2e2402b99163d1d59756e5f207ae21cccba4c\trefs/tags/v1.0^{}\n \n The Content-Type of the returned info/refs entity SHOULD be\n \"text/plain; charset=utf-8\", but MAY be any content type.\n@@ -187,17 +187,17 @@ each ref and its known value.  The file SHOULD be sorted by name\n according to the C locale ordering.  The file SHOULD NOT include\n the default ref named 'HEAD'.\n \n-\tinfo_refs     = *( ref_record )\n-\tref_record    = any_ref | peeled_ref\n+  info_refs        =  *( ref_record )\n+  ref_record       =  any_ref | peeled_ref\n \n-\tany_ref       = id HT name LF\n-\tpeeled_ref    = id HT name LF\n-\t                id HT name \"^{}\" LF\n-\tid            = 40*HEX\n+  any_ref          =  id HT name LF\n+  peeled_ref       =  id HT name LF\n+\t\t      id HT name \"^{}\" LF\n+  id               =  40*HEX\n \n-\tHEX           = \"0\"..\"9\" | \"a\"..\"f\"\n-\tLF            = <US-ASCII LF, linefeed (10)>\n-\tHT            = <US-ASCII HT, horizontal-tab (9)>\n+  HEX              =  \"0\"..\"9\" | \"a\"..\"f\"\n+  LF               =  <US-ASCII LF, linefeed (10)>\n+  HT               =  <US-ASCII HT, horizontal-tab (9)>\n \n Smart Clients\n ~~~~~~~~~~~~~\n@@ -211,26 +211,26 @@ The request MUST contain exactly one query parameter,\n name the client wishes to contact to complete the operation.\n The request MUST NOT contain additional query parameters.\n \n-\tC: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0\n-\n-\tdumb server reply:\n-\tS: 200 OK\n-\tS:\n-\tS: 95dcfa3633004da0049d3d0fa03f80589cbcaf31\trefs/heads/maint\n-\tS: d049f6c27a2244e12041955e262a404c7faba355\trefs/heads/master\n-\tS: 2cb58b79488a98d2721cea644875a8dd0026b115\trefs/tags/v1.0\n-\tS: a3c2e2402b99163d1d59756e5f207ae21cccba4c\trefs/tags/v1.0^{}\n-\n-\tsmart server reply:\n-\tS: 200 OK\n-\tS: Content-Type: application/x-git-upload-pack-advertisement\n-\tS: Cache-Control: no-cache\n-\tS:\n-\tS: ....# service=git-upload-pack\n-\tS: ....95dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint\\0 multi_ack\n-\tS: ....d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\n-\tS: ....2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0\n-\tS: ....a3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}\n+   C: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0\n+\n+   dumb server reply:\n+   S: 200 OK\n+   S:\n+   S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31\trefs/heads/maint\n+   S: d049f6c27a2244e12041955e262a404c7faba355\trefs/heads/master\n+   S: 2cb58b79488a98d2721cea644875a8dd0026b115\trefs/tags/v1.0\n+   S: a3c2e2402b99163d1d59756e5f207ae21cccba4c\trefs/tags/v1.0^{}\n+\n+   smart server reply:\n+   S: 200 OK\n+   S: Content-Type: application/x-git-upload-pack-advertisement\n+   S: Cache-Control: no-cache\n+   S:\n+   S: ....# service=git-upload-pack\n+   S: ....95dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint\\0 multi_ack\n+   S: ....d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\n+   S: ....2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0\n+   S: ....a3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}\n \n Dumb Server Response\n ^^^^^^^^^^^^^^^^^^^^\n@@ -281,28 +281,28 @@ the C locale ordering.  The stream SHOULD include the default ref\n named 'HEAD' as the first ref.  The stream MUST include capability\n declarations behind a NUL on the first ref.\n \n-\tsmart_reply    = PKT-LINE(\"# service=$servicename\" LF)\n-\t                 ref_list\n-\t                 \"0000\"\n-\tref_list       = empty_list | non_empty_list\n+  smart_reply      =  PKT-LINE(\"# service=$servicename\" LF)\n+\t\t      ref_list\n+\t\t      \"0000\"\n+  ref_list         =  empty_list | non_empty_list\n \n-\tempty_list     = PKT-LINE(id SP \"capabilities^{}\" NUL cap_list LF)\n+  empty_list       =  PKT-LINE(id SP \"capabilities^{}\" NUL cap_list LF)\n \n-\tnon_empty_list = PKT-LINE(id SP name NUL cap_list LF)\n-\t                 *ref_record\n+  non_empty_list   =  PKT-LINE(id SP name NUL cap_list LF)\n+\t\t      *ref_record\n \n-\tcap_list      = *(SP capability) SP\n-\tref_record    = any_ref | peeled_ref\n+  cap_list         =  *(SP capability) SP\n+  ref_record       =  any_ref | peeled_ref\n \n-\tany_ref       = PKT-LINE(id SP name LF)\n-\tpeeled_ref    = PKT-LINE(id SP name LF)\n-\t                PKT-LINE(id SP name \"^{}\" LF\n-\tid            = 40*HEX\n+  any_ref          =  PKT-LINE(id SP name LF)\n+  peeled_ref       =  PKT-LINE(id SP name LF)\n+\t\t      PKT-LINE(id SP name \"^{}\" LF\n+  id               =  40*HEX\n \n-\tHEX           = \"0\"..\"9\" | \"a\"..\"f\"\n-\tNL            = <US-ASCII NUL, null (0)>\n-\tLF            = <US-ASCII LF,  linefeed (10)>\n-\tSP            = <US-ASCII SP,  horizontal-tab (9)>\n+  HEX              =  \"0\"..\"9\" | \"a\"..\"f\"\n+  NL               =  <US-ASCII NUL, null (0)>\n+  LF               =  <US-ASCII LF,  linefeed (10)>\n+  SP               =  <US-ASCII SP,  horizontal-tab (9)>\n \n \n Smart Service git-upload-pack\n@@ -312,19 +312,19 @@ This service reads from the remote repository.\n Clients MUST first perform ref discovery with\n '$GIT_URL/info/refs?service=git-upload-pack'.\n \n-\tC: POST $GIT_URL/git-upload-pack HTTP/1.0\n-\tC: Content-Type: application/x-git-upload-pack-request\n-\tC:\n-\tC: ....want 0a53e9ddeaddad63ad106860237bbf53411d11a7\n-\tC: ....have 441b40d833fdfa93eb2908e52742248faf0ee993\n-\tC: 0000\n+   C: POST $GIT_URL/git-upload-pack HTTP/1.0\n+   C: Content-Type: application/x-git-upload-pack-request\n+   C:\n+   C: ....want 0a53e9ddeaddad63ad106860237bbf53411d11a7\n+   C: ....have 441b40d833fdfa93eb2908e52742248faf0ee993\n+   C: 0000\n \n-\tS: 200 OK\n-\tS: Content-Type: application/x-git-upload-pack-result\n-\tS: Cache-Control: no-cache\n-\tS:\n-\tS: ....ACK %s, continue\n-\tS: ....NAK\n+   S: 200 OK\n+   S: Content-Type: application/x-git-upload-pack-result\n+   S: Cache-Control: no-cache\n+   S:\n+   S: ....ACK %s, continue\n+   S: ....NAK\n \n Clients MUST NOT reuse or revalidate a cached reponse.\n Servers MUST include sufficient Cache-Control headers\n@@ -336,23 +336,23 @@ Clients MUST send at least one 'want' command in the request body.\n Clients MUST NOT reference an id in a 'want' command which did not\n appear in the response obtained through ref discovery.\n \n-\tcompute_request   = want_list\n-\t                    have_list\n-\t                    request_end\n-\trequest_end       = \"0000\" | \"done\"\n+  compute_request  =  want_list\n+\t\t      have_list\n+\t\t      request_end\n+  request_end      =  \"0000\" | \"done\"\n \n-\twant_list         = PKT-LINE(want NUL cap_list LF)\n-\t                    *(want_pkt)\n-\twant_pkt          = PKT-LINE(want LF)\n-\twant              = \"want\" SP id\n-\tcap_list          = *(SP capability) SP\n+  want_list        =  PKT-LINE(want NUL cap_list LF)\n+\t\t      *(want_pkt)\n+  want_pkt         =  PKT-LINE(want LF)\n+  want             =  \"want\" SP id\n+  cap_list         =  *(SP capability) SP\n \n-\thave_list         = *PKT-LINE(\"have\" SP id LF)\n+  have_list        =  *PKT-LINE(\"have\" SP id LF)\n \n-\tcommand           = create | delete | update\n-\tcreate            = 40*\"0\" SP new_id SP name\n-\tdelete            = old_id SP 40*\"0\" SP name\n-\tupdate            = old_id SP new_id SP name\n+  command          =  create | delete | update\n+  create           =  40*\"0\" SP new_id SP name\n+  delete           =  old_id SP 40*\"0\" SP name\n+  update           =  old_id SP new_id SP name\n \n TODO: Document this further.\n TODO: Don't use uppercase for variable names below.\n@@ -396,16 +396,16 @@ The computation to select the minimal pack proceeds as follows\n  one compute step:\n  (c) Send one $GIT_URL/git-upload-pack request:\n \n-\tC: 0032want <WANT #1>...............................\n-\tC: 0032want <WANT #2>...............................\n-\t....\n-\tC: 0032have <COMMON #1>.............................\n-\tC: 0032have <COMMON #2>.............................\n-\t....\n-\tC: 0032have <HAVE #1>...............................\n-\tC: 0032have <HAVE #2>...............................\n-\t....\n-\tC: 0000\n+   C: 0032want <WANT #1>...............................\n+   C: 0032want <WANT #2>...............................\n+   ....\n+   C: 0032have <COMMON #1>.............................\n+   C: 0032have <COMMON #2>.............................\n+   ....\n+   C: 0032have <HAVE #1>...............................\n+   C: 0032have <HAVE #2>...............................\n+   ....\n+   C: 0000\n \n      The stream is organized into \"commands\", with each command\n      appearing by itself in a pkt-line.  Within a command line\n@@ -434,13 +434,13 @@ The computation to select the minimal pack proceeds as follows\n      emptied C_PENDING it should include a \"done\" command to let\n      the server know it won't proceed:\n \n-\tC: 0009done\n+   C: 0009done\n \n   (s) Parse the git-upload-pack request:\n \n       Verify all objects in WANT are directly reachable from refs.\n \n-\t  The server MAY walk backwards through history or through\n+      The server MAY walk backwards through history or through\n       the reflog to permit slightly stale requests.\n \n       If no WANT objects are received, send an error:\n@@ -466,7 +466,7 @@ TODO: Define error if an invalid want is requested.\n      request ends with \"done\", it replies with the pack.\n \n TODO: Document the pack based response\n-\tS: PACK...\n+   S: PACK...\n \n      The returned stream is the side-band-64k protocol supported\n      by the git-upload-pack service, and the pack is embedded into\n@@ -495,18 +495,18 @@ This service modifies the remote repository.\n Clients MUST first perform ref discovery with\n '$GIT_URL/info/refs?service=git-receive-pack'.\n \n-\tC: POST $GIT_URL/git-receive-pack HTTP/1.0\n-\tC: Content-Type: application/x-git-receive-pack-request\n-\tC:\n-\tC: ....0a53e9ddeaddad63ad106860237bbf53411d11a7 441b40d833fdfa93eb2908e52742248faf0ee993 refs/heads/maint\\0 report-status\n-\tC: 0000\n-\tC: PACK....\n+   C: POST $GIT_URL/git-receive-pack HTTP/1.0\n+   C: Content-Type: application/x-git-receive-pack-request\n+   C:\n+   C: ....0a53e9ddeaddad63ad106860237bbf53411d11a7 441b40d833fdfa93eb2908e52742248faf0ee993 refs/heads/maint\\0 report-status\n+   C: 0000\n+   C: PACK....\n \n-\tS: 200 OK\n-\tS: Content-Type: application/x-git-receive-pack-result\n-\tS: Cache-Control: no-cache\n-\tS:\n-\tS: ....\n+   S: 200 OK\n+   S: Content-Type: application/x-git-receive-pack-result\n+   S: Cache-Control: no-cache\n+   S:\n+   S: ....\n \n Clients MUST NOT reuse or revalidate a cached reponse.\n Servers MUST include sufficient Cache-Control headers\n@@ -518,18 +518,18 @@ Clients MUST send at least one command in the request body.\n Within the command portion of the request body clients SHOULD send\n the id obtained through ref discovery as old_id.\n \n-\tupdate_request    = command_list\n-\t                    \"PACK\" <binary data>\n+  update_request   =  command_list\n+\t\t      \"PACK\" <binary data>\n \n-\tcommand_list      = PKT-LINE(command NUL cap_list LF)\n-\t                    *(command_pkt)\n-\tcommand_pkt       = PKT-LINE(command LF)\n-\tcap_list          = *(SP capability) SP\n+  command_list     =  PKT-LINE(command NUL cap_list LF)\n+\t\t      *(command_pkt)\n+  command_pkt      =  PKT-LINE(command LF)\n+  cap_list         =  *(SP capability) SP\n \n-\tcommand           = create | delete | update\n-\tcreate            = 40*\"0\" SP new_id SP name\n-\tdelete            = old_id SP 40*\"0\" SP name\n-\tupdate            = old_id SP new_id SP name\n+  command          =  create | delete | update\n+  create           =  40*\"0\" SP new_id SP name\n+  delete           =  old_id SP 40*\"0\" SP name\n+  update           =  old_id SP new_id SP name\n \n TODO: Document this further.\n \n-- \n1.8.4.rc4.527.g303b16c\n"},{"id":"227333","messageId":"1378832878-12811-4-git-send-email-rctay89@gmail.com","threadId":"21164","inReplyTo":"1378832878-12811-3-git-send-email-rctay89@gmail.com","subject":"[PATCH 03/14] capitalize key words according to RFC 2119","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2013-09-10T17:07:47Z","receivedAt":"2013-09-10T17:07:47Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n Documentation/technical/http-protocol.txt | 17 +++++++++++------\n 1 file changed, 11 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nindex 70a1648..55753bb 100644\n--- a/Documentation/technical/http-protocol.txt\n+++ b/Documentation/technical/http-protocol.txt\n@@ -11,6 +11,10 @@ protocol URLs to smart URLs.  This permits all users to have the\n same published URL, and the peers automatically select the most\n efficient transport available to them.\n \n+The key words \"MUST\", \"MUST NOT\", \"REQUIRED\", \"SHALL\", \"SHALL\n+NOT\", \"SHOULD\", \"SHOULD NOT\", \"RECOMMENDED\",  \"MAY\", and\n+\"OPTIONAL\" in this document are to be interpreted as described in\n+RFC 2119.\n \n URL Format\n ----------\n@@ -29,7 +33,7 @@ supplied $GIT_URL string.\n \n Clients MUST strip a trailing '/', if present, from the user supplied\n $GIT_URL string to prevent empty path tokens ('//') from appearing\n-in any URL sent to a server.  Compatible clients must expand\n+in any URL sent to a server.  Compatible clients MUST expand\n '$GIT_URL/info/refs' as 'foo/info/refs' and not 'foo//info/refs'.\n \n \n@@ -66,7 +70,7 @@ Session State\n -------------\n \n The Git over HTTP protocol (much like HTTP itself) is stateless\n-from the perspective of the HTTP server side.  All state must be\n+from the perspective of the HTTP server side.  All state MUST be\n retained and managed by the client process.  This permits simple\n round-robin load-balancing on the server side, without needing to\n worry about state management.\n@@ -158,7 +162,7 @@ references by making a request for the special info/refs file of\n the repository.\n \n Dumb HTTP clients MUST NOT include search/query parameters when\n-fetching the info/refs file.  (That is, '?' must not appear in the\n+fetching the info/refs file.  (That is, '?' MUST NOT appear in the\n requested URL.)\n \n    C: GET $GIT_URL/info/refs HTTP/1.0\n@@ -390,7 +394,7 @@ The computation to select the minimal pack proceeds as follows\n \n  (c) Start a queue, C_PENDING, ordered by commit time (popping newest\n      first).  Add all client refs.  When a commit is popped from\n-     the queue its parents should be automatically inserted back.\n+     the queue its parents SHOULD be automatically inserted back.\n      Commits MUST only enter the queue once.\n \n  one compute step:\n@@ -431,7 +435,7 @@ The computation to select the minimal pack proceeds as follows\n \n      If the client has sent 256 HAVE commits and has not yet\n      received one of those back from S_COMMON, or the client has\n-     emptied C_PENDING it should include a \"done\" command to let\n+     emptied C_PENDING it SHOULD include a \"done\" command to let\n      the server know it won't proceed:\n \n    C: 0009done\n@@ -470,7 +474,7 @@ TODO: Document the pack based response\n \n      The returned stream is the side-band-64k protocol supported\n      by the git-upload-pack service, and the pack is embedded into\n-     stream 1.  Progress messages from the server side may appear\n+     stream 1.  Progress messages from the server side MAY appear\n      in stream 2.\n \n      Here a \"closed set of objects\" is defined to have at least\n@@ -538,5 +542,6 @@ References\n ----------\n \n link:http://www.ietf.org/rfc/rfc1738.txt[RFC 1738: Uniform Resource Locators (URL)]\n+link:http://www.ietf.org/rfc/rfc2119.txt[RFC 2119: Key words for use in RFCs to Indicate Requirement Levels]\n link:http://www.ietf.org/rfc/rfc2616.txt[RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1]\n \n-- \n1.8.4.rc4.527.g303b16c\n"},{"id":"227334","messageId":"1378832878-12811-5-git-send-email-rctay89@gmail.com","threadId":"21164","inReplyTo":"1378832878-12811-4-git-send-email-rctay89@gmail.com","subject":"[PATCH 04/14] normalize rules with RFC 5234","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2013-09-10T17:07:48Z","receivedAt":"2013-09-10T17:07:48Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Drop LF, SP which are defined in RFC 5234.\n\nReplace HT with HTAB (also defined in the RFC).\n\nUse '/' instead of '|', as the RFC does.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n Documentation/technical/http-protocol.txt | 26 +++++++++-----------------\n 1 file changed, 9 insertions(+), 17 deletions(-)\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nindex 55753bb..ff91bb0 100644\n--- a/Documentation/technical/http-protocol.txt\n+++ b/Documentation/technical/http-protocol.txt\n@@ -192,16 +192,13 @@ according to the C locale ordering.  The file SHOULD NOT include\n the default ref named 'HEAD'.\n \n   info_refs        =  *( ref_record )\n-  ref_record       =  any_ref | peeled_ref\n+  ref_record       =  any_ref / peeled_ref\n \n-  any_ref          =  id HT name LF\n-  peeled_ref       =  id HT name LF\n-\t\t      id HT name \"^{}\" LF\n+  any_ref          =  id HTAB name LF\n+  peeled_ref       =  id HTAB name LF\n+\t\t      id HTAB name \"^{}\" LF\n   id               =  40*HEX\n \n-  HEX              =  \"0\"..\"9\" | \"a\"..\"f\"\n-  LF               =  <US-ASCII LF, linefeed (10)>\n-  HT               =  <US-ASCII HT, horizontal-tab (9)>\n \n Smart Clients\n ~~~~~~~~~~~~~\n@@ -288,7 +285,7 @@ declarations behind a NUL on the first ref.\n   smart_reply      =  PKT-LINE(\"# service=$servicename\" LF)\n \t\t      ref_list\n \t\t      \"0000\"\n-  ref_list         =  empty_list | non_empty_list\n+  ref_list         =  empty_list / non_empty_list\n \n   empty_list       =  PKT-LINE(id SP \"capabilities^{}\" NUL cap_list LF)\n \n@@ -296,18 +293,13 @@ declarations behind a NUL on the first ref.\n \t\t      *ref_record\n \n   cap_list         =  *(SP capability) SP\n-  ref_record       =  any_ref | peeled_ref\n+  ref_record       =  any_ref / peeled_ref\n \n   any_ref          =  PKT-LINE(id SP name LF)\n   peeled_ref       =  PKT-LINE(id SP name LF)\n \t\t      PKT-LINE(id SP name \"^{}\" LF\n   id               =  40*HEX\n \n-  HEX              =  \"0\"..\"9\" | \"a\"..\"f\"\n-  NL               =  <US-ASCII NUL, null (0)>\n-  LF               =  <US-ASCII LF,  linefeed (10)>\n-  SP               =  <US-ASCII SP,  horizontal-tab (9)>\n-\n \n Smart Service git-upload-pack\n ------------------------------\n@@ -343,7 +335,7 @@ appear in the response obtained through ref discovery.\n   compute_request  =  want_list\n \t\t      have_list\n \t\t      request_end\n-  request_end      =  \"0000\" | \"done\"\n+  request_end      =  \"0000\" / \"done\"\n \n   want_list        =  PKT-LINE(want NUL cap_list LF)\n \t\t      *(want_pkt)\n@@ -353,7 +345,7 @@ appear in the response obtained through ref discovery.\n \n   have_list        =  *PKT-LINE(\"have\" SP id LF)\n \n-  command          =  create | delete | update\n+  command          =  create / delete / update\n   create           =  40*\"0\" SP new_id SP name\n   delete           =  old_id SP 40*\"0\" SP name\n   update           =  old_id SP new_id SP name\n@@ -530,7 +522,7 @@ the id obtained through ref discovery as old_id.\n   command_pkt      =  PKT-LINE(command LF)\n   cap_list         =  *(SP capability) SP\n \n-  command          =  create | delete | update\n+  command          =  create / delete / update\n   create           =  40*\"0\" SP new_id SP name\n   delete           =  old_id SP 40*\"0\" SP name\n   update           =  old_id SP new_id SP name\n-- \n1.8.4.rc4.527.g303b16c\n"},{"id":"227345","messageId":"1378832878-12811-6-git-send-email-rctay89@gmail.com","threadId":"21164","inReplyTo":"1378832878-12811-5-git-send-email-rctay89@gmail.com","subject":"[PATCH 05/14] drop rules, etc. common to the pack protocol","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2013-09-10T17:07:49Z","receivedAt":"2013-09-10T17:07:49Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Use obj-id in lieu of id (defined as 40*HEX).\n\nUse zero-id in lieu of 40*\"0\".\n\nUse refname in lieu of name (not defined).\n\nDrop section on capabilities, since they are already available in\nprotocol-capabilities.txt.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n--\n\npkt-line format section was dropped in response to Junio's comments:\n\n  From:   Junio C Hamano <gitster@pobox.com>\n  Message-ID: <7vskdss3ei.fsf@alter.siamese.dyndns.org>\n\n  > +pkt-line Format\n  > +---------------\n  > ...\n  > +Examples (as C-style strings):\n  > +\n  > +  pkt-line          actual value\n  > +  ---------------------------------\n  > +  \"0006a\\n\"         \"a\\n\"\n  > +  \"0005a\"           \"a\"\n  > +  \"000bfoobar\\n\"    \"foobar\\n\"\n  > +  \"0004\"            \"\"\n  > +\n  > +A pkt-line with a length of 0 (\"0000\") is a special case and MUST\n  > +be treated as a message break or terminator in the payload.\n\n  Isn't this \"MUST be\" wrong?\n\n  It is not an advice to the implementors, but the protocol specification\n  itself defines what the flush packet means.  IOW, \"The author of this\n  specification, Shawn, MUST treat a flush packet as a message break or\n  terminator in the payload, when designing this protocol.\"\n\nCapabilities and 'command' ABNF rules under git-upload-pack were\ndropped by Nguyễn:\n\n  Message-ID: <1377092713-25434-1-git-send-email-pclouds@gmail.com>\n---\n Documentation/technical/http-protocol.txt | 85 ++++---------------------------\n 1 file changed, 10 insertions(+), 75 deletions(-)\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nindex ff91bb0..a8d28ba 100644\n--- a/Documentation/technical/http-protocol.txt\n+++ b/Documentation/technical/http-protocol.txt\n@@ -84,34 +84,6 @@ as described by RFC 2616 (HTTP/1.1).  Servers SHOULD ignore any\n cookies sent by a client.\n \n \n-pkt-line Format\n----------------\n-\n-Much (but not all) of the payload is described around pkt-lines.\n-\n-A pkt-line is a variable length binary string.  The first four bytes\n-of the line indicates the total length of the line, in hexadecimal.\n-The total length includes the 4 bytes used to denote the length.\n-A line SHOULD BE terminated by an LF, which if present MUST be\n-included in the total length.\n-\n-A pkt-line MAY contain binary data, so implementors MUST ensure all\n-pkt-line parsing/formatting routines are 8-bit clean.  The maximum\n-length of a pkt-line's data is 65532 bytes (65536 - 4).\n-\n-Examples (as C-style strings):\n-\n-  pkt-line          actual value\n-  ---------------------------------\n-  \"0006a\\n\"         \"a\\n\"\n-  \"0005a\"           \"a\"\n-  \"000bfoobar\\n\"    \"foobar\\n\"\n-  \"0004\"            \"\"\n-\n-A pkt-line with a length of 0 (\"0000\") is a special case and MUST\n-be treated as a message break or terminator in the payload.\n-\n-\n General Request Processing\n --------------------------\n \n@@ -194,11 +166,9 @@ the default ref named 'HEAD'.\n   info_refs        =  *( ref_record )\n   ref_record       =  any_ref / peeled_ref\n \n-  any_ref          =  id HTAB name LF\n-  peeled_ref       =  id HTAB name LF\n-\t\t      id HTAB name \"^{}\" LF\n-  id               =  40*HEX\n-\n+  any_ref          =  obj-id HTAB refname LF\n+  peeled_ref       =  obj-id HTAB refname LF\n+\t\t      obj-id HTAB refname \"^{}\" LF\n \n Smart Clients\n ~~~~~~~~~~~~~\n@@ -283,23 +253,7 @@ named 'HEAD' as the first ref.  The stream MUST include capability\n declarations behind a NUL on the first ref.\n \n   smart_reply      =  PKT-LINE(\"# service=$servicename\" LF)\n-\t\t      ref_list\n-\t\t      \"0000\"\n-  ref_list         =  empty_list / non_empty_list\n-\n-  empty_list       =  PKT-LINE(id SP \"capabilities^{}\" NUL cap_list LF)\n-\n-  non_empty_list   =  PKT-LINE(id SP name NUL cap_list LF)\n-\t\t      *ref_record\n-\n-  cap_list         =  *(SP capability) SP\n-  ref_record       =  any_ref / peeled_ref\n-\n-  any_ref          =  PKT-LINE(id SP name LF)\n-  peeled_ref       =  PKT-LINE(id SP name LF)\n-\t\t      PKT-LINE(id SP name \"^{}\" LF\n-  id               =  40*HEX\n-\n+\t\t      advertised-refs\n \n Smart Service git-upload-pack\n ------------------------------\n@@ -345,31 +299,9 @@ appear in the response obtained through ref discovery.\n \n   have_list        =  *PKT-LINE(\"have\" SP id LF)\n \n-  command          =  create / delete / update\n-  create           =  40*\"0\" SP new_id SP name\n-  delete           =  old_id SP 40*\"0\" SP name\n-  update           =  old_id SP new_id SP name\n-\n TODO: Document this further.\n TODO: Don't use uppercase for variable names below.\n \n-Capability include-tag\n-~~~~~~~~~~~~~~~~~~~~~~\n-\n-When packing an object that an annotated tag points at, include the\n-tag object too.  Clients can request this if they want to fetch\n-tags, but don't know which tags they will need until after they\n-receive the branch data.  By enabling include-tag an entire call\n-to upload-pack can be avoided.\n-\n-Capability thin-pack\n-~~~~~~~~~~~~~~~~~~~~\n-\n-When packing a deltified object the base is not included if the base\n-is reachable from an object listed in the COMMON set by the client.\n-This reduces the bandwidth required to transfer, but it does slightly\n-increase processing time for the client to save the pack to disk.\n-\n The Negotiation Algorithm\n ~~~~~~~~~~~~~~~~~~~~~~~~~\n The computation to select the minimal pack proceeds as follows\n@@ -523,9 +455,9 @@ the id obtained through ref discovery as old_id.\n   cap_list         =  *(SP capability) SP\n \n   command          =  create / delete / update\n-  create           =  40*\"0\" SP new_id SP name\n-  delete           =  old_id SP 40*\"0\" SP name\n-  update           =  old_id SP new_id SP name\n+  create           =  zero-id SP new_id SP refname\n+  delete           =  old_id SP zero-id SP refname\n+  update           =  old_id SP new_id SP refname\n \n TODO: Document this further.\n \n@@ -536,4 +468,7 @@ References\n link:http://www.ietf.org/rfc/rfc1738.txt[RFC 1738: Uniform Resource Locators (URL)]\n link:http://www.ietf.org/rfc/rfc2119.txt[RFC 2119: Key words for use in RFCs to Indicate Requirement Levels]\n link:http://www.ietf.org/rfc/rfc2616.txt[RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1]\n+link:technical/pack-protocol.txt\n+link:technical/protocol-common.txt\n+link:technical/protocol-capabilities.txt\n \n-- \n1.8.4.rc4.527.g303b16c\n"},{"id":"227336","messageId":"1378832878-12811-7-git-send-email-rctay89@gmail.com","threadId":"21164","inReplyTo":"1378832878-12811-6-git-send-email-rctay89@gmail.com","subject":"[PATCH 06/14] reword behaviour on missing repository or objects","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2013-09-10T17:07:50Z","receivedAt":"2013-09-10T17:07:50Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"From: \"Shawn O. Pearce\" <spearce@spearce.org>\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n--\nTo Shawn: sign-off-by needed.\n\nBased on:\n\n  From: \"Shawn O. Pearce\" <spearce@spearce.org>\n  Message-ID: <20091016142135.GR10505@spearce.org>\n\n  Mike Hommey <mh@glandium.org> wrote:\n  > On Thu, Oct 15, 2009 at 10:59:25PM -0700, H. Peter Anvin wrote:\n  > > On 10/10/2009 03:12 AM, Antti-Juhani Kaijanaho wrote:\n  > > > On 2009-10-09, Junio C Hamano <gitster@pobox.com> wrote:\n  > > >>> +If there is no repository at $GIT_URL, the server MUST respond with\n  > > >>> +the '404 Not Found' HTTP status code.\n  > > >>\n  > > >> We may also want to add\n  > > >>\n  > > >>     If there is no object at $GIT_URL/some/path, the server MUST respond\n  > > >>     with the '404 Not Found' HTTP status code.\n  > > >>\n  > > >> to help dumb clients.\n  > > >\n  > > > In both cases - is it really necessary to forbid the use of 410 (Gone)?\n\n  My original text got taken a bit out of context here.  I guess MUST\n  was too strong of a word.  I more ment something like:\n\n    If there is no repository at $GIT_URL, the server MUST NOT respond\n    with '200 OK' and a valid info/refs response.  A server SHOULD\n    respond with '404 Not Found', '410 Gone', or any other suitable\n    HTTP status code which does not imply the resource exists as\n    requested.\n\nIn addition, address behaviour on missing objects, as suggested by\nJunio. His text (see quote in above excerpt) was not used, in favour of\na more general treatment (locations matching $GIT_URL, not just\nobjects).\n---\n Documentation/technical/http-protocol.txt | 8 ++++++--\n 1 file changed, 6 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nindex a8d28ba..412b898 100644\n--- a/Documentation/technical/http-protocol.txt\n+++ b/Documentation/technical/http-protocol.txt\n@@ -91,8 +91,12 @@ Except where noted, all standard HTTP behavior SHOULD be assumed\n by both client and server.  This includes (but is not necessarily\n limited to):\n \n-If there is no repository at $GIT_URL, the server MUST respond with\n-the '404 Not Found' HTTP status code.\n+If there is no repository at $GIT_URL, the server MUST NOT respond with\n+'200 OK' and a valid info/refs response.  Also, if the resource pointed\n+to by a location matching $GIT_URL does not exist, the server MUST NOT\n+respond with '200 OK'.  A server SHOULD respond with\n+'404 Not Found', '410 Gone', or any other suitable HTTP status code\n+which does not imply the resource exists as requested.\n \n If there is a repository at $GIT_URL, but access is not currently\n permitted, the server MUST respond with the '403 Forbidden' HTTP\n-- \n1.8.4.rc4.527.g303b16c\n"},{"id":"227337","messageId":"1378832878-12811-8-git-send-email-rctay89@gmail.com","threadId":"21164","inReplyTo":"1378832878-12811-7-git-send-email-rctay89@gmail.com","subject":"[PATCH 07/14] weaken specification over cookies for authentication","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2013-09-10T17:07:51Z","receivedAt":"2013-09-10T17:07:51Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"From: \"Shawn O. Pearce\" <spearce@spearce.org>\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n--\nTo Shawn: sign-off-by needed.\n\nBased on the discussion in\n  <20091009195035.GA15153@coredump.intra.peff.net>,\n  <20091015165228.GO10505@spearce.org> (patch),\n  <20091015173902.GA22262@sigill.intra.peff.net> (agreement)\n\n  From: \"Shawn O. Pearce\" <spearce@spearce.org>\n  Message-ID: <20091015165228.GO10505@spearce.org>\n\n  I weakend the sections on cookies:\n\n  + Authentication\n  + --------------\n  ....\n  + Servers SHOULD NOT require HTTP cookies for the purposes of\n  + authentication or access control.\n\n  and that's all we say on the matter.  I took out the Servers MUST\n  NOT line under session state.\n---\n Documentation/technical/http-protocol.txt | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nindex 412b898..2382384 100644\n--- a/Documentation/technical/http-protocol.txt\n+++ b/Documentation/technical/http-protocol.txt\n@@ -52,7 +52,7 @@ Clients SHOULD support Basic authentication as described by RFC 2616.\n Servers SHOULD support Basic authentication by relying upon the\n HTTP server placed in front of the Git server software.\n \n-Servers MUST NOT require HTTP cookies for the purposes of\n+Servers SHOULD NOT require HTTP cookies for the purposes of\n authentication or access control.\n \n Clients and servers MAY support other common forms of HTTP based\n-- \n1.8.4.rc4.527.g303b16c\n"},{"id":"227335","messageId":"1378832878-12811-9-git-send-email-rctay89@gmail.com","threadId":"21164","inReplyTo":"1378832878-12811-8-git-send-email-rctay89@gmail.com","subject":"[PATCH 08/14] mention different variations around $GIT_URL","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2013-09-10T17:07:52Z","receivedAt":"2013-09-10T17:07:52Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Based on\n\n  From:\tAlex Blewitt <Alex.Blewitt@gmail.com>\n  Message-ID: <loom.20091009T104530-586@post.gmane.org>\n\n  Shawn O. Pearce <spearce <at> spearce.org> writes:\n\n  > +URL Format\n  > +----------\n  > +\n  > +URLs for Git repositories accessed by HTTP use the standard HTTP\n  > +URL syntax documented by RFC 1738, so they are of the form:\n  > +\n  > +  http://<host>:<port>/<path>\n  > +\n  > +Within this documentation the placeholder $GIT_URL will stand for\n  > +the http:// repository URL entered by the end-user.\n\n  It's worth making clear here that $GIT_URL will be the path to the repository,\n  rather than necessarily just the host upon which the server sits. Perhaps\n  including an example, like http://example:8080/repos/example.git\n  would make it clearer that there can be a path (and so leading to\n  a request like http://example:8080/repos/example.git/info/refs?service=...\n\n  It's also worth clarifying, therefore, that multiple repositories can be served\n  by the same process (as with the git server today) by using different path(s).\n  And for those that are interested in submodules, it's worth confirming that\n  http://example/repos/master.git/child.git/info/refs?service= will ensure\n  that the repository is the 'child' git rather than anything else.\n\nThe submodule example (/master.git/child.git) seems potentially\nconfusing - it suggests a setup where the server has a route to a git\nrepo (child.git) with a parent path containing another git repo\n(master.git). It is excluded lest we be seen as encouraging such\nmind-boggling setups.\n\nWhile providing an example $GIT_URL containing a '?' (the catch-all\ngateway one), also mention a possible contradiction between the\nexactly-one-param requirement and the http client implementation in Git.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n Documentation/technical/http-protocol.txt | 22 ++++++++++++++++++++--\n 1 file changed, 20 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nindex 2382384..d0955c2 100644\n--- a/Documentation/technical/http-protocol.txt\n+++ b/Documentation/technical/http-protocol.txt\n@@ -22,15 +22,28 @@ URL Format\n URLs for Git repositories accessed by HTTP use the standard HTTP\n URL syntax documented by RFC 1738, so they are of the form:\n \n-  http://<host>:<port>/<path>\n+  http://<host>:<port>/<path>?<searchpart>\n \n Within this documentation the placeholder $GIT_URL will stand for\n the http:// repository URL entered by the end-user.\n \n-Both the \"smart\" and \"dumb\" HTTP protocols used by Git operate\n+Servers SHOULD handle all requests to locations matching $GIT_URL, as\n+both the \"smart\" and \"dumb\" HTTP protocols used by Git operate\n by appending additional path components onto the end of the user\n supplied $GIT_URL string.\n \n+An example of a dumb client requesting for a loose object:\n+\n+  $GIT_URL:     http://example.com:8080/git/repo.git\n+  URL request:  http://example.com:8080/git/repo.git/objects/d0/49f6c27a2244e12041955e262a404c7faba355\n+\n+An example of a smart request to a catch-all gateway (notice how the\n+'service' parameter is passed with '&', since a '?' was detected in\n+$GIT_URL):\n+\n+  $GIT_URL:     http://example.com/daemon.cgi?svc=git&q=\n+  URL request:  http://example.com/daemon.cgi?svc=git&q=/info/refs&service=git-receive-pack\n+\n Clients MUST strip a trailing '/', if present, from the user supplied\n $GIT_URL string to prevent empty path tokens ('//') from appearing\n in any URL sent to a server.  Compatible clients MUST expand\n@@ -186,6 +199,11 @@ The request MUST contain exactly one query parameter,\n name the client wishes to contact to complete the operation.\n The request MUST NOT contain additional query parameters.\n \n+TODO: \"exactly\" one query parameter may be too strict; see the catch-all\n+gateway $GIT_URL for an example where more than one parameter is passed.\n+In fact, the http client implementation in Git can handle similar\n+$GIT_URLs, and thus may pass more than parameter to the server.\n+\n    C: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0\n \n    dumb server reply:\n-- \n1.8.4.rc4.527.g303b16c\n"},{"id":"227338","messageId":"1378832878-12811-10-git-send-email-rctay89@gmail.com","threadId":"21164","inReplyTo":"1378832878-12811-9-git-send-email-rctay89@gmail.com","subject":"[PATCH 09/14] reduce ambiguity over '?' in $GIT_URL for dumb clients","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2013-09-10T17:07:53Z","receivedAt":"2013-09-10T17:07:53Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"From: Junio C Hamano <gitster@pobox.com>\n\nIt is unclear if '?' can be part of $GIT_URL. E.g.\n\n    $ wget http://example.xz/serve.cgi?path=git.git/info/refs\n    $ git clone http://example.xz/serve.cgi?path=git.git\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n--\n\nNotes:\n - said \"request to\" instead of Junio's \"request against\", for\n   consistency with the rest of the document.\n - said \"E.g.\" instead of \"I.e.\" since it's an example request and\n   response\n\nBased on:\n\n  From:   Junio C Hamano <gitster@pobox.com>\n  Message-ID: <7vskdss3ei.fsf@alter.siamese.dyndns.org>\n\n  > +Dumb Clients\n  > +~~~~~~~~~~~~\n  > +\n  > +HTTP clients that only support the \"dumb\" protocol MUST discover\n  > +references by making a request for the special info/refs file of\n  > +the repository.\n  > +\n  > +Dumb HTTP clients MUST NOT include search/query parameters when\n  > +fetching the info/refs file.  (That is, '?' must not appear in the\n  > +requested URL.)\n\n  It is unclear if '?' can be part of $GIT_URL. E.g.\n\n      $ wget http://example.xz/serve.cgi?path=git.git/info/refs\n      $ git clone http://example.xz/serve.cgi?path=git.git\n\n  It might be clearer to just say\n\n      Dumb HTTP clients MUST make a GET request against $GIT_URL/info/refs,\n      without any search/query parameters.  I.e.\n\n          C: GET $GIT_URL/info/refs HTTP/1.0\n\n  to also exclude methods other than GET.\n---\n Documentation/technical/http-protocol.txt | 5 ++---\n 1 file changed, 2 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nindex d0955c2..5141c6a 100644\n--- a/Documentation/technical/http-protocol.txt\n+++ b/Documentation/technical/http-protocol.txt\n@@ -150,9 +150,8 @@ HTTP clients that only support the \"dumb\" protocol MUST discover\n references by making a request for the special info/refs file of\n the repository.\n \n-Dumb HTTP clients MUST NOT include search/query parameters when\n-fetching the info/refs file.  (That is, '?' MUST NOT appear in the\n-requested URL.)\n+Dumb HTTP clients MUST make a GET request to $GIT_URL/info/refs,\n+without any search/query parameters.  E.g.\n \n    C: GET $GIT_URL/info/refs HTTP/1.0\n \n-- \n1.8.4.rc4.527.g303b16c\n"},{"id":"227339","messageId":"1378832878-12811-11-git-send-email-rctay89@gmail.com","threadId":"21164","inReplyTo":"1378832878-12811-10-git-send-email-rctay89@gmail.com","subject":"[PATCH 10/14] fix example request/responses","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2013-09-10T17:07:54Z","receivedAt":"2013-09-10T17:07:54Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Add LF for responses.\n\nFor smart interactions, add pkt-line lengths and the flush-pkt (0000) line.\n\nDrop the SP that followed NUL before capability list.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n Documentation/technical/http-protocol.txt | 35 ++++++++++++++++---------------\n 1 file changed, 18 insertions(+), 17 deletions(-)\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nindex 5141c6a..dbfff36 100644\n--- a/Documentation/technical/http-protocol.txt\n+++ b/Documentation/technical/http-protocol.txt\n@@ -157,10 +157,10 @@ without any search/query parameters.  E.g.\n \n    S: 200 OK\n    S:\n-   S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31\trefs/heads/maint\n-   S: d049f6c27a2244e12041955e262a404c7faba355\trefs/heads/master\n-   S: 2cb58b79488a98d2721cea644875a8dd0026b115\trefs/tags/v1.0\n-   S: a3c2e2402b99163d1d59756e5f207ae21cccba4c\trefs/tags/v1.0^{}\n+   S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31\trefs/heads/maint\\n\n+   S: d049f6c27a2244e12041955e262a404c7faba355\trefs/heads/master\\n\n+   S: 2cb58b79488a98d2721cea644875a8dd0026b115\trefs/tags/v1.0\\n\n+   S: a3c2e2402b99163d1d59756e5f207ae21cccba4c\trefs/tags/v1.0^{}\\n\n \n The Content-Type of the returned info/refs entity SHOULD be\n \"text/plain; charset=utf-8\", but MAY be any content type.\n@@ -208,21 +208,22 @@ $GIT_URLs, and thus may pass more than parameter to the server.\n    dumb server reply:\n    S: 200 OK\n    S:\n-   S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31\trefs/heads/maint\n-   S: d049f6c27a2244e12041955e262a404c7faba355\trefs/heads/master\n-   S: 2cb58b79488a98d2721cea644875a8dd0026b115\trefs/tags/v1.0\n-   S: a3c2e2402b99163d1d59756e5f207ae21cccba4c\trefs/tags/v1.0^{}\n+   S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31\trefs/heads/maint\\n\n+   S: d049f6c27a2244e12041955e262a404c7faba355\trefs/heads/master\\n\n+   S: 2cb58b79488a98d2721cea644875a8dd0026b115\trefs/tags/v1.0\\n\n+   S: a3c2e2402b99163d1d59756e5f207ae21cccba4c\trefs/tags/v1.0^{}\\n\n \n    smart server reply:\n    S: 200 OK\n    S: Content-Type: application/x-git-upload-pack-advertisement\n    S: Cache-Control: no-cache\n    S:\n-   S: ....# service=git-upload-pack\n-   S: ....95dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint\\0 multi_ack\n-   S: ....d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\n-   S: ....2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0\n-   S: ....a3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}\n+   S: 001e# service=git-upload-pack\\n\n+   S: 004895dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint\\0multi_ack\\n\n+   S: 0042d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\\n\n+   S: 003c2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0\\n\n+   S: 003fa3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}\\n\n+   S: 0000\n \n Dumb Server Response\n ^^^^^^^^^^^^^^^^^^^^\n@@ -286,8 +287,8 @@ Clients MUST first perform ref discovery with\n    C: POST $GIT_URL/git-upload-pack HTTP/1.0\n    C: Content-Type: application/x-git-upload-pack-request\n    C:\n-   C: ....want 0a53e9ddeaddad63ad106860237bbf53411d11a7\n-   C: ....have 441b40d833fdfa93eb2908e52742248faf0ee993\n+   C: 0032want 0a53e9ddeaddad63ad106860237bbf53411d11a7\\n\n+   C: 0032have 441b40d833fdfa93eb2908e52742248faf0ee993\\n\n    C: 0000\n \n    S: 200 OK\n@@ -383,7 +384,7 @@ The computation to select the minimal pack proceeds as follows\n      emptied C_PENDING it SHOULD include a \"done\" command to let\n      the server know it won't proceed:\n \n-   C: 0009done\n+   C: 0009done\\n\n \n   (s) Parse the git-upload-pack request:\n \n@@ -447,7 +448,7 @@ Clients MUST first perform ref discovery with\n    C: POST $GIT_URL/git-receive-pack HTTP/1.0\n    C: Content-Type: application/x-git-receive-pack-request\n    C:\n-   C: ....0a53e9ddeaddad63ad106860237bbf53411d11a7 441b40d833fdfa93eb2908e52742248faf0ee993 refs/heads/maint\\0 report-status\n+   C: ....0a53e9ddeaddad63ad106860237bbf53411d11a7 441b40d833fdfa93eb2908e52742248faf0ee993 refs/heads/maint\\0report-status\n    C: 0000\n    C: PACK....\n \n-- \n1.8.4.rc4.527.g303b16c\n"},{"id":"227340","messageId":"1378832878-12811-12-git-send-email-rctay89@gmail.com","threadId":"21164","inReplyTo":"1378832878-12811-11-git-send-email-rctay89@gmail.com","subject":"[PATCH 11/14] be clearer in place of 'remote repository' phrase","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2013-09-10T17:07:55Z","receivedAt":"2013-09-10T17:07:55Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Based on:\n\n  From:   Junio C Hamano <gitster@pobox.com>\n  Message-ID: <7vskdss3ei.fsf@alter.siamese.dyndns.org>\n\n  > +Smart Service git-upload-pack\n  > +------------------------------\n  > +This service reads from the remote repository.\n\n  The wording \"remote repository\" felt confusing.  I know it is \"from the\n  repository served by the server\", but if it were named without\n  \"upload-pack\", I might have mistaken that you are allowing to proxy a\n  request to access a third-party repository by this server.  The same\n  comment applies to the git-receive-pack service.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n Documentation/technical/http-protocol.txt | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nindex dbfff36..4bb1614 100644\n--- a/Documentation/technical/http-protocol.txt\n+++ b/Documentation/technical/http-protocol.txt\n@@ -279,7 +279,7 @@ declarations behind a NUL on the first ref.\n \n Smart Service git-upload-pack\n ------------------------------\n-This service reads from the remote repository.\n+This service reads from the repository pointed to by $GIT_URL.\n \n Clients MUST first perform ref discovery with\n '$GIT_URL/info/refs?service=git-upload-pack'.\n@@ -440,7 +440,7 @@ TODO: Document parsing response\n \n Smart Service git-receive-pack\n ------------------------------\n-This service modifies the remote repository.\n+This service modifies the repository pointed to by $GIT_URL.\n \n Clients MUST first perform ref discovery with\n '$GIT_URL/info/refs?service=git-receive-pack'.\n-- \n1.8.4.rc4.527.g303b16c\n"},{"id":"227344","messageId":"1378832878-12811-13-git-send-email-rctay89@gmail.com","threadId":"21164","inReplyTo":"1378832878-12811-12-git-send-email-rctay89@gmail.com","subject":"[PATCH 12/14] reduce confusion over smart server response behaviour","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2013-09-10T17:07:56Z","receivedAt":"2013-09-10T17:07:56Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"The MUST and the following 'If' scenario may seem contradictory at first\nglance; swap their order to alleviate this.\n\nAlso mention that the response should specifically be for the requested\nservice, for clarity's sake.\n\nBased on:\n\n  From:   Junio C Hamano <gitster@pobox.com>\n  Message-ID: <7vskdss3ei.fsf@alter.siamese.dyndns.org>\n\n  > +Smart Server Response\n  > +^^^^^^^^^^^^^^^^^^^^^\n  > +\n  > +Smart servers MUST respond with the smart server reply format.\n  > +If the server does not recognize the requested service name, or the\n  > +requested service name has been disabled by the server administrator,\n  > +the server MUST respond with the '403 Forbidden' HTTP status code.\n\n  This is a bit confusing.\n\n  If you as a server administrator want to disable the smart upload-pack for\n  one repository (but not for other repositories), you would not be able to\n  force smart clients to fall back to the dumb protocol by giving \"403\" for\n  that repository.\n\n  Maybe in 2 years somebody smarter than us will have invented a more\n  efficient git-upload-pack-2 service, which is the only fetch protocol his\n  server supports other than dumb.  If your v1 smart client asks for the\n  original git-upload-pack service and gets a \"403\", you won't be able to\n  fall back to \"dumb\".\n\n  The solution for such cases likely is to pretend as if you are a dumb\n  server for the smart request.  That unfortunately means that the first\n  sentence is misleading, and the second sentence is also an inappropriate\n  advice.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n Documentation/technical/http-protocol.txt | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nindex 4bb1614..63a089a 100644\n--- a/Documentation/technical/http-protocol.txt\n+++ b/Documentation/technical/http-protocol.txt\n@@ -234,12 +234,13 @@ description of the dumb server response.\n \n Smart Server Response\n ^^^^^^^^^^^^^^^^^^^^^\n-Smart servers MUST respond with the smart server reply format.\n-\n If the server does not recognize the requested service name, or the\n requested service name has been disabled by the server administrator,\n the server MUST respond with the '403 Forbidden' HTTP status code.\n \n+Otherwise, smart servers MUST respond with the smart server reply\n+format for the requested service name.\n+\n Cache-Control headers SHOULD be used to disable caching of the\n returned entity.\n \n-- \n1.8.4.rc4.527.g303b16c\n"},{"id":"227341","messageId":"1378832878-12811-14-git-send-email-rctay89@gmail.com","threadId":"21164","inReplyTo":"1378832878-12811-13-git-send-email-rctay89@gmail.com","subject":"[PATCH 13/14] shift dumb server response details","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2013-09-10T17:07:57Z","receivedAt":"2013-09-10T17:07:57Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Shift details like ABNF from the client section to server section. This\nis in line with the smart analogue.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n Documentation/technical/http-protocol.txt | 49 +++++++++++++++----------------\n 1 file changed, 23 insertions(+), 26 deletions(-)\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nindex 63a089a..3098aa4 100644\n--- a/Documentation/technical/http-protocol.txt\n+++ b/Documentation/technical/http-protocol.txt\n@@ -162,30 +162,6 @@ without any search/query parameters.  E.g.\n    S: 2cb58b79488a98d2721cea644875a8dd0026b115\trefs/tags/v1.0\\n\n    S: a3c2e2402b99163d1d59756e5f207ae21cccba4c\trefs/tags/v1.0^{}\\n\n \n-The Content-Type of the returned info/refs entity SHOULD be\n-\"text/plain; charset=utf-8\", but MAY be any content type.\n-Clients MUST NOT attempt to validate the returned Content-Type.\n-Dumb servers MUST NOT return a return type starting with\n-\"application/x-git-\".\n-\n-Cache-Control headers MAY be returned to disable caching of the\n-returned entity.\n-\n-When examining the response clients SHOULD only examine the HTTP\n-status code.  Valid responses are '200 OK', or '304 Not Modified'.\n-\n-The returned content is a UNIX formatted text file describing\n-each ref and its known value.  The file SHOULD be sorted by name\n-according to the C locale ordering.  The file SHOULD NOT include\n-the default ref named 'HEAD'.\n-\n-  info_refs        =  *( ref_record )\n-  ref_record       =  any_ref / peeled_ref\n-\n-  any_ref          =  obj-id HTAB refname LF\n-  peeled_ref       =  obj-id HTAB refname LF\n-\t\t      obj-id HTAB refname \"^{}\" LF\n-\n Smart Clients\n ~~~~~~~~~~~~~\n \n@@ -229,8 +205,29 @@ Dumb Server Response\n ^^^^^^^^^^^^^^^^^^^^\n Dumb servers MUST respond with the dumb server reply format.\n \n-See the prior section under dumb clients for a more detailed\n-description of the dumb server response.\n+The Content-Type of the returned info/refs entity SHOULD be\n+\"text/plain; charset=utf-8\", but MAY be any content type.\n+Clients MUST NOT attempt to validate the returned Content-Type.\n+Dumb servers MUST NOT return a return type starting with\n+\"application/x-git-\".\n+\n+Cache-Control headers MAY be returned to disable caching of the\n+returned entity.\n+\n+When examining the response clients SHOULD only examine the HTTP\n+status code.  Valid responses are '200 OK', or '304 Not Modified'.\n+\n+The returned content is a UNIX formatted text file describing\n+each ref and its known value.  The file SHOULD be sorted by name\n+according to the C locale ordering.  The file SHOULD NOT include\n+the default ref named 'HEAD'.\n+\n+  info_refs        =  *( ref_record )\n+  ref_record       =  any_ref / peeled_ref\n+\n+  any_ref          =  obj-id HTAB refname LF\n+  peeled_ref       =  obj-id HTAB refname LF\n+\t\t      obj-id HTAB refname \"^{}\" LF\n \n Smart Server Response\n ^^^^^^^^^^^^^^^^^^^^^\n-- \n1.8.4.rc4.527.g303b16c\n"},{"id":"227342","messageId":"1378832878-12811-15-git-send-email-rctay89@gmail.com","threadId":"21164","inReplyTo":"1378832878-12811-14-git-send-email-rctay89@gmail.com","subject":"[PATCH 14/14] mention effect of \"allow-tip-sha1-in-want\" capability on git-upload-pack","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2013-09-10T17:07:58Z","receivedAt":"2013-09-10T17:07:58Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"From: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n--\n\nSubject crafted by Ray Chuan, Nguyễn's s-o-b lifted from\n<1377092713-25434-1-git-send-email-pclouds@gmail.com>.\n\n---\n Documentation/technical/http-protocol.txt | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt\nindex 3098aa4..acc68ac 100644\n--- a/Documentation/technical/http-protocol.txt\n+++ b/Documentation/technical/http-protocol.txt\n@@ -304,7 +304,8 @@ Servers SHOULD support all capabilities defined here.\n \n Clients MUST send at least one 'want' command in the request body.\n Clients MUST NOT reference an id in a 'want' command which did not\n-appear in the response obtained through ref discovery.\n+appear in the response obtained through ref discovery unless the\n+server advertises capability \"allow-tip-sha1-in-want\".\n \n   compute_request  =  want_list\n \t\t      have_list\n-- \n1.8.4.rc4.527.g303b16c\n"}]}