5
5
6
6
const UrlUtil = require ( '../js/lib/urlutil' )
7
7
const Filtering = require ( './filtering' )
8
- const config = require ( '../js/constants/config' )
9
8
const appActions = require ( '../js/actions/appActions' )
10
9
const getSetting = require ( '../js/settings' ) . getSetting
11
10
const settings = require ( '../js/constants/settings' )
12
11
13
- const pdfjsBaseUrl = `chrome-extension://${ config . PDFJSExtensionId } /`
14
- const viewerBaseUrl = `${ pdfjsBaseUrl } content/web/viewer.html`
12
+ const getViewerUrl = UrlUtil . getPDFViewerUrl
13
+
14
+ /**
15
+ * Check if the request is a PDF file.
16
+ * @param {Object } details First argument of the webRequest.onHeadersReceived
17
+ * event. The properties "responseHeaders" and "url"
18
+ * are read.
19
+ * @return {boolean } True if the resource is a PDF file.
20
+ */
21
+ function isPdfFile ( details ) {
22
+ var header = details . responseHeaders [ 'Content-Type' ]
23
+ if ( header ) {
24
+ if ( header . includes ( 'application/pdf' ) ) {
25
+ return true
26
+ }
27
+ if ( header . includes ( 'application/octet-stream' ) ) {
28
+ if ( details . url . toLowerCase ( ) . indexOf ( '.pdf' ) > 0 ) {
29
+ return true
30
+ }
31
+ var cdHeader = details . responseHeaders [ 'Content-Disposition' ]
32
+ if ( cdHeader && / \. p d f ( [ " ' ] | $ ) / i. test ( cdHeader [ 0 ] ) ) {
33
+ return true
34
+ }
35
+ }
36
+ }
37
+ }
38
+
39
+ /**
40
+ * @param {Object } details First argument of the webRequest.onHeadersReceived
41
+ * event. The property "url" is read.
42
+ * @return {boolean } True if the PDF file should be downloaded.
43
+ */
44
+ function isPdfDownloadable ( details ) {
45
+ if ( details . url . indexOf ( 'pdfjs.action=download' ) >= 0 ) {
46
+ return true
47
+ }
48
+ // Display the PDF viewer regardless of the Content-Disposition header if the
49
+ // file is displayed in the main frame, since most often users want to view
50
+ // a PDF, and servers are often misconfigured.
51
+ // If the query string contains "=download", do not unconditionally force the
52
+ // viewer to open the PDF, but first check whether the Content-Disposition
53
+ // header specifies an attachment. This allows sites like Google Drive to
54
+ // operate correctly (#6106).
55
+ if ( details . type === 'main_frame' &&
56
+ details . url . indexOf ( '=download' ) === - 1 ) {
57
+ return false
58
+ }
59
+ var cdHeader = ( details . responseHeaders &&
60
+ details . responseHeaders [ 'Content-Disposition' ] )
61
+ return ( cdHeader && / ^ a t t a c h m e n t / i. test ( cdHeader [ 0 ] ) )
62
+ }
63
+
64
+ /**
65
+ * Takes a set of headers, and set "Content-Disposition: attachment".
66
+ * @param {Object } details First argument of the webRequest.onHeadersReceived
67
+ * event. The property "responseHeaders" is read and
68
+ * modified if needed.
69
+ * @return {Object|undefined } The return value for the responseHeaders property
70
+ */
71
+ function getHeadersWithContentDispositionAttachment ( details ) {
72
+ var headers = details . responseHeaders
73
+ var cdHeader = headers [ 'Content-Disposition' ] || [ ]
74
+ cdHeader . push ( 'attachment' )
75
+ headers [ 'Content-Disposition' ] = cdHeader
76
+ return headers
77
+ }
15
78
16
79
const onBeforeRequest = ( details ) => {
17
80
const result = { resourceName : 'pdfjs' }
18
- if ( ! ( details . resourceType === 'mainFrame' &&
81
+ if ( details . resourceType === 'mainFrame' &&
19
82
UrlUtil . isFileScheme ( details . url ) &&
20
- UrlUtil . isFileType ( details . url , 'pdf' ) ) ) {
21
- return result
83
+ UrlUtil . isFileType ( details . url , 'pdf' ) ) {
84
+ appActions . loadURLRequested ( details . tabId , getViewerUrl ( details . url ) )
85
+ result . cancel = true
86
+ }
87
+ return result
88
+ }
89
+
90
+ const onHeadersReceived = ( details ) => {
91
+ const result = { resourceName : 'pdfjs' }
92
+ // Don't intercept POST requests until http://crbug.com/104058 is fixed.
93
+ if ( details . resourceType === 'mainFrame' && details . method === 'GET' && isPdfFile ( details ) ) {
94
+ if ( isPdfDownloadable ( details ) ) {
95
+ // Force download by ensuring that Content-Disposition: attachment is set
96
+ result . responseHeaders = getHeadersWithContentDispositionAttachment ( details )
97
+ return result
98
+ }
99
+
100
+ // Replace frame with viewer
101
+ appActions . loadURLRequested ( details . tabId , getViewerUrl ( details . url ) )
102
+ result . cancel = true
22
103
}
23
- appActions . loadURLRequested ( details . tabId , `${ viewerBaseUrl } ?file=${ encodeURIComponent ( details . url ) } ` )
24
- result . cancel = true
25
104
return result
26
105
}
27
106
@@ -31,5 +110,6 @@ const onBeforeRequest = (details) => {
31
110
module . exports . init = ( ) => {
32
111
if ( getSetting ( settings . PDFJS_ENABLED ) ) {
33
112
Filtering . registerBeforeRequestFilteringCB ( onBeforeRequest )
113
+ Filtering . registerHeadersReceivedFilteringCB ( onHeadersReceived )
34
114
}
35
115
}
0 commit comments