Code

credential: add function for parsing url components
authorJeff King <peff@peff.net>
Sat, 10 Dec 2011 10:31:17 +0000 (05:31 -0500)
committerJunio C Hamano <gitster@pobox.com>
Mon, 12 Dec 2011 07:16:24 +0000 (23:16 -0800)
All of the components of a credential struct can be found in
a URL.  For example, the URL:

  http://foo:bar@example.com/repo.git

contains:

  protocol=http
  host=example.com
  path=repo.git
  username=foo
  password=bar

We want to be able to turn URLs into broken-down credential
structs so that we know two things:

  1. Which parts of the username/password we still need

  2. What the context of the request is (for prompting or
     as a key for storing credentials).

This code is based on http_auth_init in http.c, but needed a
few modifications in order to get all of the components that
the credential object is interested in.

Once the http code is switched over to the credential API,
then http_auth_init can just go away.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/technical/api-credentials.txt
credential.c
credential.h

index f624aefc6faae828e7caabb4b335a9c659444768..21ca6a2553280a111eca47f2f7aea37ea43ecfa0 100644 (file)
@@ -67,6 +67,10 @@ Functions
        that they may store the result to be used again.  Any errors
        from helpers are ignored.
 
        that they may store the result to be used again.  Any errors
        from helpers are ignored.
 
+`credential_from_url`::
+
+       Parse a URL into broken-down credential fields.
+
 Example
 -------
 
 Example
 -------
 
index 86397f392b8e6bd9580928653f6d1103b05f4417..c349b9aac3999ba4dbce16fd82b582cd60d61761 100644 (file)
@@ -2,6 +2,7 @@
 #include "credential.h"
 #include "string-list.h"
 #include "run-command.h"
 #include "credential.h"
 #include "string-list.h"
 #include "run-command.h"
+#include "url.h"
 
 void credential_init(struct credential *c)
 {
 
 void credential_init(struct credential *c)
 {
@@ -232,3 +233,54 @@ void credential_reject(struct credential *c)
        c->password = NULL;
        c->approved = 0;
 }
        c->password = NULL;
        c->approved = 0;
 }
+
+void credential_from_url(struct credential *c, const char *url)
+{
+       const char *at, *colon, *cp, *slash, *host, *proto_end;
+
+       credential_clear(c);
+
+       /*
+        * Match one of:
+        *   (1) proto://<host>/...
+        *   (2) proto://<user>@<host>/...
+        *   (3) proto://<user>:<pass>@<host>/...
+        */
+       proto_end = strstr(url, "://");
+       if (!proto_end)
+               return;
+       cp = proto_end + 3;
+       at = strchr(cp, '@');
+       colon = strchr(cp, ':');
+       slash = strchrnul(cp, '/');
+
+       if (!at || slash <= at) {
+               /* Case (1) */
+               host = cp;
+       }
+       else if (!colon || at <= colon) {
+               /* Case (2) */
+               c->username = url_decode_mem(cp, at - cp);
+               host = at + 1;
+       } else {
+               /* Case (3) */
+               c->username = url_decode_mem(cp, colon - cp);
+               c->password = url_decode_mem(colon + 1, at - (colon + 1));
+               host = at + 1;
+       }
+
+       if (proto_end - url > 0)
+               c->protocol = xmemdupz(url, proto_end - url);
+       if (slash - host > 0)
+               c->host = url_decode_mem(host, slash - host);
+       /* Trim leading and trailing slashes from path */
+       while (*slash == '/')
+               slash++;
+       if (*slash) {
+               char *p;
+               c->path = url_decode(slash);
+               p = c->path + strlen(c->path) - 1;
+               while (p > c->path && *p == '/')
+                       *p-- = '\0';
+       }
+}
index 2ea7d495d6bbcd4ad5496dbce759c45a880175ba..8a6d162e7b477d329b23effae8f0007163f39f3d 100644 (file)
@@ -24,5 +24,6 @@ void credential_approve(struct credential *);
 void credential_reject(struct credential *);
 
 int credential_read(struct credential *, FILE *);
 void credential_reject(struct credential *);
 
 int credential_read(struct credential *, FILE *);
+void credential_from_url(struct credential *, const char *url);
 
 #endif /* CREDENTIAL_H */
 
 #endif /* CREDENTIAL_H */