@@ -5,39 +5,60 @@ var range = require('range-parser')
55var qs = require ( 'querystring' )
66var corsify = require ( 'corsify' )
77var pkg = require ( './package.json' )
8+ var debug = require ( 'debug' ) ( 'hyperdrive-http' )
89
910module . exports = serve
1011
1112function serve ( archive , opts ) {
1213 if ( ! opts ) opts = { }
1314
15+ archive . ready ( ( ) => {
16+ debug ( 'serving' , archive . key . toString ( 'hex' ) )
17+ } )
18+
1419 return corsify ( onrequest )
1520
1621 function onrequest ( req , res ) {
1722 var name = decodeURI ( req . url . split ( '?' ) [ 0 ] )
1823 var query = qs . parse ( req . url . split ( '?' ) [ 1 ] || '' )
24+ opts . viewSource = false // reset for each request
1925
2026 var wait = ( query . wait && Number ( query . wait . toString ( ) ) ) || 0
2127 var have = archive . metadata ? archive . metadata . length : - 1
2228
23- if ( wait <= have ) return ready ( )
24- waitFor ( archive , wait , ready )
29+ if ( wait <= have ) return checkWebroot ( )
30+ waitFor ( archive , wait , checkWebroot )
31+
32+ function checkWebroot ( ) {
33+ if ( opts . web_root ) return ready ( ) // used cached version
34+ getManifest ( archive , ( err , data ) => {
35+ if ( err || ! data ) return ready ( )
36+ if ( data . web_root ) opts . web_root = data . web_root
37+ ready ( )
38+ } )
39+ }
2540
2641 function ready ( ) {
2742 var arch = / ^ \d + $ / . test ( query . version ) ? archive . checkout ( Number ( query . version ) ) : archive
43+ if ( query . viewSource ) {
44+ debug ( 'view source' , query )
45+ opts . viewSource = true
46+ }
47+ debug ( 'view' , name , 'view dir' , name [ name . length - 1 ] === '/' )
2848 if ( name [ name . length - 1 ] === '/' ) ondirectory ( arch , name , req , res , opts )
29- else onfile ( arch , name , req , res )
49+ else onfile ( arch , name , req , res , opts )
3050 }
3151 }
3252}
3353
34- function onfile ( archive , name , req , res ) {
54+ function onfile ( archive , name , req , res , opts ) {
3555 archive . stat ( name , function ( err , st ) {
3656 if ( err ) return on404 ( archive , req , res )
3757
3858 if ( st . isDirectory ( ) ) {
3959 res . statusCode = 302
4060 res . setHeader ( 'Location' , name + '/' )
61+ ondirectory ( archive , name + '/' , req , res , opts )
4162 return
4263 }
4364
@@ -66,14 +87,19 @@ function on404 (archive, req, res) {
6687
6788 if ( ! fallbackPage ) return onerror ( res , 404 , new Error ( 'Not Found, No Fallback' ) )
6889
69- archive . stat ( fallbackPage , function ( err ) {
90+ archive . stat ( ( parsed . web_root || '/' ) + fallbackPage , function ( err ) {
7091 if ( err ) return onerror ( res , 404 , err )
7192 onfile ( archive , fallbackPage , req , res )
7293 } )
7394 } )
7495}
7596
7697function ondirectory ( archive , name , req , res , opts ) {
98+ debug ( 'ondirectory:' , name , 'options' , opts )
99+ if ( opts . viewSource ) return ondirectoryindex ( archive , name , req , res , opts )
100+
101+ if ( name === '/' && opts . web_root ) name = opts . web_root
102+ if ( name [ name . length - 1 ] !== '/' ) name = name + '/'
77103 archive . stat ( name + 'index.html' , function ( err ) {
78104 if ( err ) return ondirectoryindex ( archive , name , req , res , opts )
79105 onfile ( archive , name + 'index.html' , req , res )
@@ -107,7 +133,7 @@ function ondirectoryindex (archive, name, req, res, opts) {
107133 `
108134
109135 var footer = opts . footer ? 'Archive version: ' + archive . version : null
110- var html = toHTML ( { directory : name , script : ( ! opts . live || archive . _checkout ) ? null : script , footer : footer } , entries )
136+ var html = toHTML ( { directory : name , script : ( ! opts . live || archive . _checkout ) ? null : script , footer : footer } , entries )
111137 res . setHeader ( 'Content-Type' , 'text/html; charset=utf-8' )
112138 res . setHeader ( 'Content-Length' , Buffer . byteLength ( html ) )
113139 if ( opts . exposeHeaders ) {
@@ -121,7 +147,7 @@ function ondirectoryindex (archive, name, req, res, opts) {
121147
122148function getManifest ( archive , cb ) {
123149 archive . readFile ( '/dat.json' , 'utf-8' , function ( err , data ) {
124- if ( err ) cb ( err )
150+ if ( err ) return cb ( err )
125151 try {
126152 var parsed = JSON . parse ( data )
127153 } catch ( e ) {
@@ -141,7 +167,7 @@ function waitFor (archive, until, cb) { // this feels a bit hacky, TODO: make le
141167 if ( ! archive . metadata ) archive . once ( 'ready' , waitFor . bind ( null , archive , until , cb ) )
142168 if ( archive . metadata . length >= until ) return cb ( )
143169 archive . metadata . setMaxListeners ( 0 )
144- archive . metadata . once ( 'append' , waitFor . bind ( null , archive , until , cb ) )
170+ archive . metadata . update ( waitFor . bind ( null , archive , until , cb ) )
145171}
146172
147173function onerror ( res , status , err ) {
0 commit comments