/ * *
* @ licstart The following is the entire license notice for the
* Javascript code in this page
*
* Copyright 2017 Mozilla Foundation
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
*
* @ licend The above is the entire license notice for the
* Javascript code in this page
* /
'use strict' ;
Object . defineProperty ( exports , "__esModule" , {
value : true
} ) ;
exports . PDFNodeStream = undefined ;
var _createClass = function ( ) { function defineProperties ( target , props ) { for ( var i = 0 ; i < props . length ; i ++ ) { var descriptor = props [ i ] ; descriptor . enumerable = descriptor . enumerable || false ; descriptor . configurable = true ; if ( "value" in descriptor ) descriptor . writable = true ; Object . defineProperty ( target , descriptor . key , descriptor ) ; } } return function ( Constructor , protoProps , staticProps ) { if ( protoProps ) defineProperties ( Constructor . prototype , protoProps ) ; if ( staticProps ) defineProperties ( Constructor , staticProps ) ; return Constructor ; } ; } ( ) ;
var _util = require ( '../shared/util' ) ;
var _network _utils = require ( './network_utils' ) ;
function _possibleConstructorReturn ( self , call ) { if ( ! self ) { throw new ReferenceError ( "this hasn't been initialised - super() hasn't been called" ) ; } return call && ( typeof call === "object" || typeof call === "function" ) ? call : self ; }
function _inherits ( subClass , superClass ) { if ( typeof superClass !== "function" && superClass !== null ) { throw new TypeError ( "Super expression must either be null or a function, not " + typeof superClass ) ; } subClass . prototype = Object . create ( superClass && superClass . prototype , { constructor : { value : subClass , enumerable : false , writable : true , configurable : true } } ) ; if ( superClass ) Object . setPrototypeOf ? Object . setPrototypeOf ( subClass , superClass ) : subClass . _ _proto _ _ = superClass ; }
function _classCallCheck ( instance , Constructor ) { if ( ! ( instance instanceof Constructor ) ) { throw new TypeError ( "Cannot call a class as a function" ) ; } }
var fs = require ( 'fs' ) ;
var http = require ( 'http' ) ;
var https = require ( 'https' ) ;
var url = require ( 'url' ) ;
var fileUriRegex = /^file:\/\/\/[a-zA-Z]:\// ;
var PDFNodeStream = function ( ) {
function PDFNodeStream ( source ) {
_classCallCheck ( this , PDFNodeStream ) ;
this . source = source ;
this . url = url . parse ( source . url ) ;
this . isHttp = this . url . protocol === 'http:' || this . url . protocol === 'https:' ;
this . isFsUrl = this . url . protocol === 'file:' || ! this . url . host ;
this . httpHeaders = this . isHttp && source . httpHeaders || { } ;
this . _fullRequest = null ;
this . _rangeRequestReaders = [ ] ;
}
_createClass ( PDFNodeStream , [ {
key : 'getFullReader' ,
value : function getFullReader ( ) {
( 0 , _util . assert ) ( ! this . _fullRequest ) ;
this . _fullRequest = this . isFsUrl ? new PDFNodeStreamFsFullReader ( this ) : new PDFNodeStreamFullReader ( this ) ;
return this . _fullRequest ;
}
} , {
key : 'getRangeReader' ,
value : function getRangeReader ( start , end ) {
var rangeReader = this . isFsUrl ? new PDFNodeStreamFsRangeReader ( this , start , end ) : new PDFNodeStreamRangeReader ( this , start , end ) ;
this . _rangeRequestReaders . push ( rangeReader ) ;
return rangeReader ;
}
} , {
key : 'cancelAllRequests' ,
value : function cancelAllRequests ( reason ) {
if ( this . _fullRequest ) {
this . _fullRequest . cancel ( reason ) ;
}
var readers = this . _rangeRequestReaders . slice ( 0 ) ;
readers . forEach ( function ( reader ) {
reader . cancel ( reason ) ;
} ) ;
}
} ] ) ;
return PDFNodeStream ;
} ( ) ;
var BaseFullReader = function ( ) {
function BaseFullReader ( stream ) {
_classCallCheck ( this , BaseFullReader ) ;
this . _url = stream . url ;
this . _done = false ;
this . _errored = false ;
this . _reason = null ;
this . onProgress = null ;
var source = stream . source ;
this . _contentLength = source . length ;
this . _loaded = 0 ;
this . _disableRange = source . disableRange || false ;
this . _rangeChunkSize = source . rangeChunkSize ;
if ( ! this . _rangeChunkSize && ! this . _disableRange ) {
this . _disableRange = true ;
}
this . _isStreamingSupported = ! source . disableStream ;
this . _isRangeSupported = ! source . disableRange ;
this . _readableStream = null ;
this . _readCapability = ( 0 , _util . createPromiseCapability ) ( ) ;
this . _headersCapability = ( 0 , _util . createPromiseCapability ) ( ) ;
}
_createClass ( BaseFullReader , [ {
key : 'read' ,
value : function read ( ) {
var _this = this ;
return this . _readCapability . promise . then ( function ( ) {
if ( _this . _done ) {
return Promise . resolve ( {
value : undefined ,
done : true
} ) ;
}
if ( _this . _errored ) {
return Promise . reject ( _this . _reason ) ;
}
var chunk = _this . _readableStream . read ( ) ;
if ( chunk === null ) {
_this . _readCapability = ( 0 , _util . createPromiseCapability ) ( ) ;
return _this . read ( ) ;
}
_this . _loaded += chunk . length ;
if ( _this . onProgress ) {
_this . onProgress ( {
loaded : _this . _loaded ,
total : _this . _contentLength
} ) ;
}
var buffer = new Uint8Array ( chunk ) . buffer ;
return Promise . resolve ( {
value : buffer ,
done : false
} ) ;
} ) ;
}
} , {
key : 'cancel' ,
value : function cancel ( reason ) {
if ( ! this . _readableStream ) {
this . _error ( reason ) ;
return ;
}
this . _readableStream . destroy ( reason ) ;
}
} , {
key : '_error' ,
value : function _error ( reason ) {
this . _errored = true ;
this . _reason = reason ;
this . _readCapability . resolve ( ) ;
}
} , {
key : '_setReadableStream' ,
value : function _setReadableStream ( readableStream ) {
var _this2 = this ;
this . _readableStream = readableStream ;
readableStream . on ( 'readable' , function ( ) {
_this2 . _readCapability . resolve ( ) ;
} ) ;
readableStream . on ( 'end' , function ( ) {
readableStream . destroy ( ) ;
_this2 . _done = true ;
_this2 . _readCapability . resolve ( ) ;
} ) ;
readableStream . on ( 'error' , function ( reason ) {
_this2 . _error ( reason ) ;
} ) ;
if ( ! this . _isStreamingSupported && this . _isRangeSupported ) {
this . _error ( new _util . AbortException ( 'streaming is disabled' ) ) ;
}
if ( this . _errored ) {
this . _readableStream . destroy ( this . _reason ) ;
}
}
} , {
key : 'headersReady' ,
get : function get ( ) {
return this . _headersCapability . promise ;
}
} , {
key : 'contentLength' ,
get : function get ( ) {
return this . _contentLength ;
}
} , {
key : 'isRangeSupported' ,
get : function get ( ) {
return this . _isRangeSupported ;
}
} , {
key : 'isStreamingSupported' ,
get : function get ( ) {
return this . _isStreamingSupported ;
}
} ] ) ;
return BaseFullReader ;
} ( ) ;
var BaseRangeReader = function ( ) {
function BaseRangeReader ( stream ) {
_classCallCheck ( this , BaseRangeReader ) ;
this . _url = stream . url ;
this . _done = false ;
this . _errored = false ;
this . _reason = null ;
this . onProgress = null ;
this . _loaded = 0 ;
this . _readableStream = null ;
this . _readCapability = ( 0 , _util . createPromiseCapability ) ( ) ;
var source = stream . source ;
this . _isStreamingSupported = ! source . disableStream ;
}
_createClass ( BaseRangeReader , [ {
key : 'read' ,
value : function read ( ) {
var _this3 = this ;
return this . _readCapability . promise . then ( function ( ) {
if ( _this3 . _done ) {
return Promise . resolve ( {
value : undefined ,
done : true
} ) ;
}
if ( _this3 . _errored ) {
return Promise . reject ( _this3 . _reason ) ;
}
var chunk = _this3 . _readableStream . read ( ) ;
if ( chunk === null ) {
_this3 . _readCapability = ( 0 , _util . createPromiseCapability ) ( ) ;
return _this3 . read ( ) ;
}
_this3 . _loaded += chunk . length ;
if ( _this3 . onProgress ) {
_this3 . onProgress ( { loaded : _this3 . _loaded } ) ;
}
var buffer = new Uint8Array ( chunk ) . buffer ;
return Promise . resolve ( {
value : buffer ,
done : false
} ) ;
} ) ;
}
} , {
key : 'cancel' ,
value : function cancel ( reason ) {
if ( ! this . _readableStream ) {
this . _error ( reason ) ;
return ;
}
this . _readableStream . destroy ( reason ) ;
}
} , {
key : '_error' ,
value : function _error ( reason ) {
this . _errored = true ;
this . _reason = reason ;
this . _readCapability . resolve ( ) ;
}
} , {
key : '_setReadableStream' ,
value : function _setReadableStream ( readableStream ) {
var _this4 = this ;
this . _readableStream = readableStream ;
readableStream . on ( 'readable' , function ( ) {
_this4 . _readCapability . resolve ( ) ;
} ) ;
readableStream . on ( 'end' , function ( ) {
readableStream . destroy ( ) ;
_this4 . _done = true ;
_this4 . _readCapability . resolve ( ) ;
} ) ;
readableStream . on ( 'error' , function ( reason ) {
_this4 . _error ( reason ) ;
} ) ;
if ( this . _errored ) {
this . _readableStream . destroy ( this . _reason ) ;
}
}
} , {
key : 'isStreamingSupported' ,
get : function get ( ) {
return this . _isStreamingSupported ;
}
} ] ) ;
return BaseRangeReader ;
} ( ) ;
function createRequestOptions ( url , headers ) {
return {
protocol : url . protocol ,
auth : url . auth ,
host : url . hostname ,
port : url . port ,
path : url . path ,
method : 'GET' ,
headers : headers
} ;
}
var PDFNodeStreamFullReader = function ( _BaseFullReader ) {
_inherits ( PDFNodeStreamFullReader , _BaseFullReader ) ;
function PDFNodeStreamFullReader ( stream ) {
_classCallCheck ( this , PDFNodeStreamFullReader ) ;
var _this5 = _possibleConstructorReturn ( this , ( PDFNodeStreamFullReader . _ _proto _ _ || Object . getPrototypeOf ( PDFNodeStreamFullReader ) ) . call ( this , stream ) ) ;
var handleResponse = function handleResponse ( response ) {
_this5 . _headersCapability . resolve ( ) ;
_this5 . _setReadableStream ( response ) ;
var _validateRangeRequest = ( 0 , _network _utils . validateRangeRequestCapabilities ) ( {
getResponseHeader : function getResponseHeader ( name ) {
return _this5 . _readableStream . headers [ name . toLowerCase ( ) ] ;
} ,
isHttp : stream . isHttp ,
rangeChunkSize : _this5 . _rangeChunkSize ,
disableRange : _this5 . _disableRange
} ) ,
allowRangeRequests = _validateRangeRequest . allowRangeRequests ,
suggestedLength = _validateRangeRequest . suggestedLength ;
if ( allowRangeRequests ) {
_this5 . _isRangeSupported = true ;
}
_this5 . _contentLength = suggestedLength ;
} ;
_this5 . _request = null ;
if ( _this5 . _url . protocol === 'http:' ) {
_this5 . _request = http . request ( createRequestOptions ( _this5 . _url , stream . httpHeaders ) , handleResponse ) ;
} else {
_this5 . _request = https . request ( createRequestOptions ( _this5 . _url , stream . httpHeaders ) , handleResponse ) ;
}
_this5 . _request . on ( 'error' , function ( reason ) {
_this5 . _errored = true ;
_this5 . _reason = reason ;
_this5 . _headersCapability . reject ( reason ) ;
} ) ;
_this5 . _request . end ( ) ;
return _this5 ;
}
return PDFNodeStreamFullReader ;
} ( BaseFullReader ) ;
var PDFNodeStreamRangeReader = function ( _BaseRangeReader ) {
_inherits ( PDFNodeStreamRangeReader , _BaseRangeReader ) ;
function PDFNodeStreamRangeReader ( stream , start , end ) {
_classCallCheck ( this , PDFNodeStreamRangeReader ) ;
var _this6 = _possibleConstructorReturn ( this , ( PDFNodeStreamRangeReader . _ _proto _ _ || Object . getPrototypeOf ( PDFNodeStreamRangeReader ) ) . call ( this , stream ) ) ;
_this6 . _httpHeaders = { } ;
for ( var property in stream . httpHeaders ) {
var value = stream . httpHeaders [ property ] ;
if ( typeof value === 'undefined' ) {
continue ;
}
_this6 . _httpHeaders [ property ] = value ;
}
_this6 . _httpHeaders [ 'Range' ] = 'bytes=' + start + '-' + ( end - 1 ) ;
_this6 . _request = null ;
if ( _this6 . _url . protocol === 'http:' ) {
_this6 . _request = http . request ( createRequestOptions ( _this6 . _url , _this6 . _httpHeaders ) , function ( response ) {
_this6 . _setReadableStream ( response ) ;
} ) ;
} else {
_this6 . _request = https . request ( createRequestOptions ( _this6 . _url , _this6 . _httpHeaders ) , function ( response ) {
_this6 . _setReadableStream ( response ) ;
} ) ;
}
_this6 . _request . on ( 'error' , function ( reason ) {
_this6 . _errored = true ;
_this6 . _reason = reason ;
} ) ;
_this6 . _request . end ( ) ;
return _this6 ;
}
return PDFNodeStreamRangeReader ;
} ( BaseRangeReader ) ;
var PDFNodeStreamFsFullReader = function ( _BaseFullReader2 ) {
_inherits ( PDFNodeStreamFsFullReader , _BaseFullReader2 ) ;
function PDFNodeStreamFsFullReader ( stream ) {
_classCallCheck ( this , PDFNodeStreamFsFullReader ) ;
var _this7 = _possibleConstructorReturn ( this , ( PDFNodeStreamFsFullReader . _ _proto _ _ || Object . getPrototypeOf ( PDFNodeStreamFsFullReader ) ) . call ( this , stream ) ) ;
var path = decodeURIComponent ( _this7 . _url . path ) ;
if ( fileUriRegex . test ( _this7 . _url . href ) ) {
path = path . replace ( /^\// , '' ) ;
}
fs . lstat ( path , function ( error , stat ) {
if ( error ) {
_this7 . _errored = true ;
_this7 . _reason = error ;
_this7 . _headersCapability . reject ( error ) ;
return ;
}
_this7 . _contentLength = stat . size ;
_this7 . _setReadableStream ( fs . createReadStream ( path ) ) ;
_this7 . _headersCapability . resolve ( ) ;
} ) ;
return _this7 ;
}
return PDFNodeStreamFsFullReader ;
} ( BaseFullReader ) ;
var PDFNodeStreamFsRangeReader = function ( _BaseRangeReader2 ) {
_inherits ( PDFNodeStreamFsRangeReader , _BaseRangeReader2 ) ;
function PDFNodeStreamFsRangeReader ( stream , start , end ) {
_classCallCheck ( this , PDFNodeStreamFsRangeReader ) ;
var _this8 = _possibleConstructorReturn ( this , ( PDFNodeStreamFsRangeReader . _ _proto _ _ || Object . getPrototypeOf ( PDFNodeStreamFsRangeReader ) ) . call ( this , stream ) ) ;
var path = decodeURIComponent ( _this8 . _url . path ) ;
if ( fileUriRegex . test ( _this8 . _url . href ) ) {
path = path . replace ( /^\// , '' ) ;
}
_this8 . _setReadableStream ( fs . createReadStream ( path , {
start : start ,
end : end - 1
} ) ) ;
return _this8 ;
}
return PDFNodeStreamFsRangeReader ;
} ( BaseRangeReader ) ;
exports . PDFNodeStream = PDFNodeStream ;