Add #:username and #:password arguments to net/git-checkout
This can be used to provide authentication for accessing repositories over HTTP(S), such as private repositories on GitHub.
This commit is contained in:
parent
00644821de
commit
d409fb5e2e
|
@ -36,7 +36,9 @@ for information on command-line arguments and flags.
|
||||||
[(git) 9418]
|
[(git) 9418]
|
||||||
[(http) 80]
|
[(http) 80]
|
||||||
[(https) 443])]
|
[(https) 443])]
|
||||||
[#:strict-links? strict-links? any/c #f])
|
[#:strict-links? strict-links? any/c #f]
|
||||||
|
[#:username username (or/c string? #f) (current-git-username)]
|
||||||
|
[#:password password (or/c string? #f) (current-git-password)])
|
||||||
string?]{
|
string?]{
|
||||||
|
|
||||||
Contacts the server at @racket[hostname] and @racket[port]
|
Contacts the server at @racket[hostname] and @racket[port]
|
||||||
|
@ -96,6 +98,20 @@ If @racket[strict-links?] is true, then the checkout fails with an
|
||||||
error if it would produce a symbolic link that refers to an absolute path
|
error if it would produce a symbolic link that refers to an absolute path
|
||||||
or to a relative path that contains up-directory elements.
|
or to a relative path that contains up-directory elements.
|
||||||
|
|
||||||
|
If both @racket[username] and @racket[password] are non-@racket[#f]
|
||||||
|
@emph{and} @racket[transport] is @racket['http] or @racket['https], then
|
||||||
|
the provided credentials are passed to the remote server using HTTP Basic
|
||||||
|
Authentication.
|
||||||
|
|
||||||
@history[#:added "6.1.1.1"
|
@history[#:added "6.1.1.1"
|
||||||
#:changed "6.3" @elem{Added the @racket[initial-error] argument.}
|
#:changed "6.3" @elem{Added the @racket[initial-error] argument.}
|
||||||
#:changed "6.2.900.17" @elem{Added the @racket[strict-links?] argument.}]}
|
#:changed "6.2.900.17" @elem{Added the @racket[strict-links?] argument.}
|
||||||
|
#:changed "6.6.0.5" @elem{Added the @racket[username] and @racket[password] arguments.}]}
|
||||||
|
|
||||||
|
@deftogether[(@defparam[current-git-username username (or/c string? #f)]
|
||||||
|
@defparam[current-git-password password (or/c string? #f)])]{
|
||||||
|
Parameters used by @racket[git-checkout] as the default values of the
|
||||||
|
@racket[_username] and @racket[_password] arguments to control
|
||||||
|
authentication with the remote server.
|
||||||
|
|
||||||
|
@history[#:added "6.6.0.5"]}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
file/gunzip
|
file/gunzip
|
||||||
file/private/check-path
|
file/private/check-path
|
||||||
openssl/sha1
|
openssl/sha1
|
||||||
|
net/base64
|
||||||
net/url
|
net/url
|
||||||
net/head
|
net/head
|
||||||
net/http-client
|
net/http-client
|
||||||
|
@ -16,10 +17,15 @@
|
||||||
;; http://stefan.saasen.me/articles/git-clone-in-haskell-from-the-bottom-up/
|
;; http://stefan.saasen.me/articles/git-clone-in-haskell-from-the-bottom-up/
|
||||||
;; provided many helpful hints for this implementation.
|
;; provided many helpful hints for this implementation.
|
||||||
|
|
||||||
(provide git-checkout)
|
(provide git-checkout
|
||||||
|
current-git-username
|
||||||
|
current-git-password)
|
||||||
|
|
||||||
(define-logger git-checkout)
|
(define-logger git-checkout)
|
||||||
|
|
||||||
|
(define current-git-username (make-parameter #f))
|
||||||
|
(define current-git-password (make-parameter #f))
|
||||||
|
|
||||||
;; Like `git clone`, but producing just the checkout
|
;; Like `git clone`, but producing just the checkout
|
||||||
(define (git-checkout host
|
(define (git-checkout host
|
||||||
repo
|
repo
|
||||||
|
@ -35,7 +41,9 @@
|
||||||
#:clean-tmp-dir? [clean-tmp-dir? (not given-tmp-dir)]
|
#:clean-tmp-dir? [clean-tmp-dir? (not given-tmp-dir)]
|
||||||
#:verify-server? [verify? #t]
|
#:verify-server? [verify? #t]
|
||||||
#:port [given-port #f]
|
#:port [given-port #f]
|
||||||
#:strict-links? [strict-links? #f])
|
#:strict-links? [strict-links? #f]
|
||||||
|
#:username [username (current-git-username)]
|
||||||
|
#:password [password (current-git-password)])
|
||||||
(let retry-loop ([given-depth given-depth])
|
(let retry-loop ([given-depth given-depth])
|
||||||
(define tmp-dir (or given-tmp-dir
|
(define tmp-dir (or given-tmp-dir
|
||||||
(make-temporary-file "git~a" 'directory)))
|
(make-temporary-file "git~a" 'directory)))
|
||||||
|
@ -51,7 +59,7 @@
|
||||||
|
|
||||||
(status "Contacting ~a" host)
|
(status "Contacting ~a" host)
|
||||||
(define-values (i o dumb-protocol?)
|
(define-values (i o dumb-protocol?)
|
||||||
(initial-connect transport host verify? port repo status))
|
(initial-connect transport host verify? port repo status username password))
|
||||||
((let/ec esc
|
((let/ec esc
|
||||||
(dynamic-wind
|
(dynamic-wind
|
||||||
void
|
void
|
||||||
|
@ -106,7 +114,7 @@
|
||||||
|
|
||||||
;; Tell the server that we're ready for the objects
|
;; Tell the server that we're ready for the objects
|
||||||
(write-pkt o "done\n")
|
(write-pkt o "done\n")
|
||||||
(set!-values (i o) (done-step transport host verify? port repo i o))
|
(set!-values (i o) (done-step transport host verify? port repo username password i o))
|
||||||
|
|
||||||
(when depth
|
(when depth
|
||||||
;; If we wrote `deepen`, then the server replies with `shallow`s.
|
;; If we wrote `deepen`, then the server replies with `shallow`s.
|
||||||
|
@ -189,18 +197,23 @@
|
||||||
;; ----------------------------------------
|
;; ----------------------------------------
|
||||||
;; Transports: git, http, and https
|
;; Transports: git, http, and https
|
||||||
|
|
||||||
(define http-request-headers
|
(define (http-request-headers username password)
|
||||||
;; bitbucket.org seems to require a "git" value for "User-Agent",
|
;; bitbucket.org seems to require a "git" value for "User-Agent",
|
||||||
;; otherwise it returns a "broken link" web page
|
;; otherwise it returns a "broken link" web page
|
||||||
'("User-Agent: git/1.9"))
|
(define base-headers '("User-Agent: git/1.9"))
|
||||||
|
;; include an Authorization header if credentials are provided
|
||||||
|
(if (and username password)
|
||||||
|
(cons (~a "Authorization: Basic " (base64-encode (string->bytes/utf-8 (~a username ":" password)) #""))
|
||||||
|
base-headers)
|
||||||
|
base-headers))
|
||||||
|
|
||||||
;; initial-connect: transport-sym string bool natural string status-proc
|
;; initial-connect: transport-sym string bool natural string status-proc string string
|
||||||
;; -> (values input-port output-port boolean)
|
;; -> (values input-port output-port boolean)
|
||||||
;; Contacts the server and returns an output port for writing
|
;; Contacts the server and returns an output port for writing
|
||||||
;; the request (ignored if not needed for the the transport)
|
;; the request (ignored if not needed for the the transport)
|
||||||
;; and an input port from reading the available references. The
|
;; and an input port from reading the available references. The
|
||||||
;; boolean result indicates whether the protocol is "dumb".
|
;; boolean result indicates whether the protocol is "dumb".
|
||||||
(define (initial-connect transport host verify? port repo status)
|
(define (initial-connect transport host verify? port repo status username password)
|
||||||
(case transport
|
(case transport
|
||||||
[(git)
|
[(git)
|
||||||
(define-values (i o) (tcp-or-tunnel-connect "git" host port))
|
(define-values (i o) (tcp-or-tunnel-connect "git" host port))
|
||||||
|
@ -212,7 +225,7 @@
|
||||||
(define-values (i headers)
|
(define-values (i headers)
|
||||||
(parameterize ([current-https-protocol (ssl-context verify?)])
|
(parameterize ([current-https-protocol (ssl-context verify?)])
|
||||||
(get-pure-port/headers (string->url url-str)
|
(get-pure-port/headers (string->url url-str)
|
||||||
http-request-headers
|
(http-request-headers username password)
|
||||||
#:redirections 5)))
|
#:redirections 5)))
|
||||||
(define ok? #f)
|
(define ok? #f)
|
||||||
(dynamic-wind
|
(dynamic-wind
|
||||||
|
@ -256,12 +269,12 @@
|
||||||
(close-input-port i)
|
(close-input-port i)
|
||||||
(values (open-input-bytes #"") (open-output-bytes))]))
|
(values (open-input-bytes #"") (open-output-bytes))]))
|
||||||
|
|
||||||
;; done-step: transport-sym string bool natural string input-port output-port
|
;; done-step: transport-sym string bool natural string string string input-port output-port
|
||||||
;; -> (values input-port output-port)
|
;; -> (values input-port output-port)
|
||||||
;; Replaces the connection, if appropriate to the transport, after
|
;; Replaces the connection, if appropriate to the transport, after
|
||||||
;; writing the wanted references and before reading the server's
|
;; writing the wanted references and before reading the server's
|
||||||
;; response.
|
;; response.
|
||||||
(define (done-step transport host verify? port repo i o)
|
(define (done-step transport host verify? port repo username password i o)
|
||||||
(case transport
|
(case transport
|
||||||
[(git) (values i o)]
|
[(git) (values i o)]
|
||||||
[(http https)
|
[(http https)
|
||||||
|
@ -274,7 +287,7 @@
|
||||||
"/git-upload-pack"))
|
"/git-upload-pack"))
|
||||||
s
|
s
|
||||||
(append
|
(append
|
||||||
http-request-headers
|
(http-request-headers username password)
|
||||||
(list "Content-Type: application/x-git-upload-pack-request")))))
|
(list "Content-Type: application/x-git-upload-pack-request")))))
|
||||||
(values i (open-output-nowhere))]))
|
(values i (open-output-nowhere))]))
|
||||||
|
|
||||||
|
@ -1109,6 +1122,10 @@
|
||||||
(set! ref branch/tag/commit)]
|
(set! ref branch/tag/commit)]
|
||||||
[("--tmp") dir "Write temporary files to <dir>"
|
[("--tmp") dir "Write temporary files to <dir>"
|
||||||
(set! tmp-dir dir)]
|
(set! tmp-dir dir)]
|
||||||
|
[("-u" "--username") username "Username used to authenticate over HTTP(S)"
|
||||||
|
(current-git-username username)]
|
||||||
|
[("-p" "--password") password "Password used to authenticate over HTTP(S)"
|
||||||
|
(current-git-password password)]
|
||||||
[("--quiet") "Suppress status printouts"
|
[("--quiet") "Suppress status printouts"
|
||||||
(set! status-printf void)]
|
(set! status-printf void)]
|
||||||
#:args (host repo dest)
|
#:args (host repo dest)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user