@@ -42,7 +42,8 @@ var mime = {
4242 * @api private
4343 */
4444
45- var bundle = / \+ ( (?: \+ ) ? [ \w \- ] + ) * (?: \. j s ) $ / g;
45+ var bundle = / \+ ( (?: \+ ) ? [ \w \- ] + ) * (?: \. v \d + \. \d + \. \d + ) ? (?: \. j s ) $ /
46+ , versioning = / \. v \d + \. \d + \. \d + (?: \. j s ) $ / ;
4647
4748/**
4849 * Export the constructor
@@ -120,10 +121,14 @@ Static.prototype.init = function () {
120121 build ( self . manager . get ( 'transports' ) , callback ) ;
121122 } ) ;
122123
124+ this . add ( '/socket.io.v' , { mime : mime . js } , function ( path , callback ) {
125+ build ( self . manager . get ( 'transports' ) , callback ) ;
126+ } ) ;
127+
123128 // allow custom builds based on url paths
124129 this . add ( '/socket.io+' , { mime : mime . js } , function ( path , callback ) {
125130 var available = self . manager . get ( 'transports' )
126- , matches = bundle . exec ( path )
131+ , matches = path . match ( bundle )
127132 , transports = [ ] ;
128133
129134 if ( ! matches ) return callback ( 'No valid transports' ) ;
@@ -217,7 +222,7 @@ Static.prototype.has = function (path) {
217222 , i = keys . length ;
218223
219224 while ( i -- ) {
220- if ( ! ! ~ path . indexOf ( keys [ i ] ) ) return this . paths [ keys [ i ] ] ;
225+ if ( - ~ path . indexOf ( keys [ i ] ) ) return this . paths [ keys [ i ] ] ;
221226 }
222227
223228 return false ;
@@ -271,7 +276,13 @@ Static.prototype.write = function (path, req, res) {
271276 function write ( status , headers , content , encoding ) {
272277 try {
273278 res . writeHead ( status , headers || undefined ) ;
274- res . end ( content || '' , encoding || undefined ) ;
279+
280+ // only write content if it's not a HEAD request and we actually have
281+ // some content to write (304's doesn't have content).
282+ res . end (
283+ req . method !== 'HEAD' && content ? content : ''
284+ , encoding || undefined
285+ ) ;
275286 } catch ( e ) { }
276287 }
277288
@@ -291,19 +302,28 @@ Static.prototype.write = function (path, req, res) {
291302 var accept = req . headers [ 'accept-encoding' ] || ''
292303 , gzip = ! ! ~ accept . toLowerCase ( ) . indexOf ( 'gzip' )
293304 , mime = reply . mime
305+ , versioned = reply . versioned
294306 , headers = {
295307 'Content-Type' : mime . type
296308 } ;
297309
298310 // check if we can add a etag
299- if ( self . manager . enabled ( 'browser client etag' ) && reply . etag ) {
311+ if ( self . manager . enabled ( 'browser client etag' ) && reply . etag && ! versioned ) {
300312 headers [ 'Etag' ] = reply . etag ;
301313 }
302314
303- // check if we can send gzip data
315+ // see if we need to set Expire headers because the path is versioned
316+ if ( versioned ) {
317+ var expires = self . manager . get ( 'browser client expires' ) ;
318+ headers [ 'Cache-Control' ] = 'private, x-gzip-ok="", max-age=' + expires ;
319+ headers [ 'Date' ] = new Date ( ) . toUTCString ( ) ;
320+ headers [ 'Expires' ] = new Date ( Date . now ( ) + ( expires * 1000 ) ) . toUTCString ( ) ;
321+ }
322+
304323 if ( gzip && reply . gzip ) {
305324 headers [ 'Content-Length' ] = reply . gzip . length ;
306325 headers [ 'Content-Encoding' ] = 'gzip' ;
326+ headers [ 'Vary' ] = 'Accept-Encoding' ;
307327 write ( 200 , headers , reply . gzip . content , mime . encoding ) ;
308328 } else {
309329 headers [ 'Content-Length' ] = reply . length ;
@@ -342,6 +362,7 @@ Static.prototype.write = function (path, req, res) {
342362 , length : content . length
343363 , mime : details . mime
344364 , etag : etag || client . version
365+ , versioned : versioning . test ( path )
345366 } ;
346367
347368 // check if gzip is enabled
0 commit comments