1- var spawn = require ( 'child_process' ) . spawn ;
2- var path = require ( 'path' ) . posix ;
3- var url = require ( 'url' ) ;
4- var backend = require ( 'git-http-backend' ) ;
5- var fixturez = require ( 'fixturez' ) ;
1+ var spawn = require ( 'child_process' ) . spawn
2+ var fs = require ( 'fs' )
3+ var path = require ( 'path' )
4+ var url = require ( 'url' )
5+
6+ var auth = require ( 'basic-auth' )
7+ var chalk = require ( 'chalk' )
8+ var fixturez = require ( 'fixturez' )
9+ var backend = require ( 'git-http-backend' )
10+ var htpasswd = require ( 'htpasswd-js' )
611
712function factory ( config ) {
813 if ( ! config . root ) throw new Error ( 'Missing required "gitHttpServer.root" config option' )
914 if ( ! config . route ) throw new Error ( 'Missing required "gitHttpServer.route" config option' )
1015 if ( ! config . route . startsWith ( '/' ) ) throw new Error ( '"gitHttpServer.route" must start with a "/"' )
1116 // TODO: Make this configurable in karma.conf.js
12- var f = fixturez ( config . root , { root : process . cwd ( ) } )
17+ var f = fixturez ( config . root , { root : process . cwd ( ) , glob : config . glob } )
1318
1419 function getGitDir ( req ) {
1520 var u = url . parse ( req . url )
1621 if ( u . pathname . startsWith ( config . route ) ) {
1722 if ( req . method === 'GET' && u . pathname . endsWith ( '/info/refs' ) ) {
1823 let gitdir = u . pathname . replace ( config . route , '' ) . replace ( / \/ i n f o \/ r e f s $ / , '' ) . replace ( / ^ \/ / , '' )
19- let fixtureName = path . basename ( gitdir )
24+ let fixtureName = path . posix . basename ( gitdir )
2025 return f . find ( fixtureName )
2126 }
2227 if ( req . method === 'POST' && req . headers [ 'content-type' ] === 'application/x-git-upload-pack-request' ) {
2328 let gitdir = u . pathname . replace ( config . route , '' ) . replace ( / \/ g i t - u p l o a d - p a c k $ / , '' ) . replace ( / ^ \/ / , '' )
24- let fixtureName = path . basename ( gitdir )
29+ let fixtureName = path . posix . basename ( gitdir )
2530 return f . find ( fixtureName )
2631 }
2732 if ( req . method === 'POST' && req . headers [ 'content-type' ] === 'application/x-git-receive-pack-request' ) {
2833 let gitdir = u . pathname . replace ( config . route , '' ) . replace ( / \/ g i t - r e c e i v e - p a c k $ / , '' ) . replace ( / ^ \/ / , '' )
29- let fixtureName = path . basename ( gitdir )
34+ let fixtureName = path . posix . basename ( gitdir )
3035 return f . copy ( fixtureName )
3136 }
3237 }
3338 return null
3439 }
3540
36- return function middleware ( req , res , next ) {
37- var gitdir = getGitDir ( req ) ;
38- if ( gitdir == null ) return next ( ) ;
41+ return async function middleware ( req , res , next ) {
42+ if ( ! next ) next = ( ) => void ( 0 )
43+ try {
44+ var gitdir = getGitDir ( req )
45+ } catch ( err ) {
46+ res . statusCode = 404
47+ res . end ( err . message + '\n' )
48+ console . log ( chalk . red ( '[git-http-server] 404 ' + req . url ) )
49+ return
50+ }
51+ if ( gitdir == null ) return next ( )
52+
53+ // Check for a .htaccess file
54+ let data = null
55+ try {
56+ data = fs . readFileSync ( path . join ( gitdir , '.htpasswd' ) , 'utf8' )
57+ } catch ( err ) {
58+ // no .htaccess file, proceed without authentication
59+ }
60+ if ( data ) {
61+ // The previous line would have failed if there wasn't an .htaccess file, so
62+ // we must treat this as protected.
63+ let cred = auth . parse ( req . headers [ 'authorization' ] )
64+ if ( cred === undefined ) {
65+ res . statusCode = 401
66+ res . setHeader ( 'WWW-Authenticate' , 'Basic' )
67+ res . end ( 'Unauthorized' + '\n' )
68+ console . log ( chalk . red ( '[git-http-server] 401 ' + req . url ) )
69+ return
70+ }
71+ let valid = await htpasswd . authenticate ( {
72+ username : cred . name ,
73+ password : cred . pass ,
74+ data
75+ } )
76+ if ( ! valid ) {
77+ res . statusCode = 401
78+ res . setHeader ( 'WWW-Authenticate' , 'Basic' )
79+ res . end ( 'Bad credentials' + '\n' )
80+ console . log ( chalk . red ( '[git-http-server] 401 ' + req . url ) )
81+ return
82+ }
83+ }
3984
4085 req . pipe ( backend ( req . url , function ( err , service ) {
4186 if ( err ) {
42- res . statusCode = 500 ;
43- res . end ( err + '\n' ) ;
44- return ;
87+ res . statusCode = 500
88+ res . end ( err + '\n' )
89+ console . log ( chalk . red ( '[git-http-server] 500 ' + req . url ) )
90+ return
4591 }
4692
47- res . setHeader ( 'content-type' , service . type ) ;
48- console . log ( '[git-http-server] ' + service . cmd + ' ' + service . args . concat ( gitdir ) . join ( ' ' ) )
49- var ps = spawn ( service . cmd , service . args . concat ( gitdir ) ) ;
50- ps . stdout . pipe ( service . createStream ( ) ) . pipe ( ps . stdin ) ;
51- } ) ) . pipe ( res ) ;
93+ res . setHeader ( 'content-type' , service . type )
94+ console . log ( chalk . green ( '[git-http-server] 200 ' + req . url ) )
95+ // console.log('[git-http-server] ' + service.cmd + ' ' + service.args.concat(gitdir).join(' '))
96+ var ps = spawn ( service . cmd , service . args . concat ( gitdir ) )
97+ ps . stdout . pipe ( service . createStream ( ) ) . pipe ( ps . stdin )
98+ } ) ) . pipe ( res )
5299 }
53100}
54101
55102factory . $inject = [ 'config.gitHttpServer' ]
56103
57- module . exports = factory
104+ module . exports = factory
0 commit comments