Skip to content

Commit

Permalink
Merge pull request #1632 from BaseAdresseNationale/fix/enable-partial…
Browse files Browse the repository at this point in the history
…-download-on-data

Fix/enable partial download on data
  • Loading branch information
nkokla authored Oct 11, 2023
2 parents 5c05032 + 728aeab commit 83ba5fd
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 31 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
"lodash": "^4.17.21",
"maplibre-gl": "^1.15.3",
"matomo-tracker": "^2.2.4",
"mime": "^3.0.0",
"next": "^13.1.2",
"papaparse": "^5.3.2",
"prop-types": "^15.8.1",
Expand All @@ -56,6 +55,7 @@
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
"react-feather": "^2.0.10",
"send": "^0.18.0",
"sharp": "^0.29.3",
"styled-components": "^6.0.7",
"underscore.string": "^3.3.6",
Expand Down
58 changes: 35 additions & 23 deletions pages/data/[[...path]].js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import fs from 'node:fs'
import path from 'node:path'
import mime from 'mime'
import send from 'send'
import PropTypes from 'prop-types'
import {Download} from 'react-feather'

Expand Down Expand Up @@ -72,33 +72,56 @@ const getDirectories = _path => (
})
)

export function getServerSideProps(context) {
const getFormatedDate = () => {
const date = new Date()
return new Intl.DateTimeFormat('fr', {year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit'}).format(date).replace(/,/g, '\'').replace(/ /g, ' ')
}

const asyncSend = (req, res, filePath) => new Promise((resolve, reject) => {
const targetFileName = path.basename(filePath)
function headers(res) {
res.setHeader('Content-Disposition', `attachment; filename="${targetFileName}"`)
}

send(req, encodeURI(filePath), {index: false})
.on('headers', headers)
.pipe(res)
.on('error', err => {
const formattedDate = getFormatedDate()
console.warn(`[${formattedDate} - ERROR]`, 'File access error:', err)
reject(err)
})
.on('end', () => {
resolve()
})
})

export async function getServerSideProps(context) {
let stat
let targetFileName
let realPath

const {path: paramPath = []} = context.params
const {params, res, req} = context
const {path: paramPath = []} = params
const fileName = `${paramPath.join('/')}`
const filePath = path.resolve(PATH, fileName)
const date = new Date()
const formattedDate = new Intl.DateTimeFormat('fr', {year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit'}).format(date).replace(/,/g, '\'').replace(/ /g, ' ')
const formattedDate = getFormatedDate()

try {
const authPath = autorizedPath(filePath)
const realPath = authPath.path

if (!authPath.auth) {
console.warn(`[${formattedDate} - WARNING]`, `Attempted illegal access to ${authPath.path}`)
context.res.statusCode = 404
res.statusCode = 404
return {
props: {errorCode: 404},
}
}

realPath = authPath.path
stat = fs.lstatSync(realPath)
targetFileName = path.basename(realPath)
} catch (err) {
console.warn(`[${formattedDate} - ERROR]`, 'File access error:', err)
context.res.statusCode = 404
res.statusCode = 404
return {
props: {errorCode: 404},
}
Expand All @@ -115,22 +138,11 @@ export function getServerSideProps(context) {
}

try {
const fileExtension = path.extname(targetFileName)
const contentType = mime.getType(fileExtension) || 'application/octet-stream'
const fileContents = fs.readFileSync(filePath)
const lastModified = stat.mtime.toUTCString()
const fileSize = stat.size
const sendToTracker = getAnalyticsPusher()

context.res.setHeader('Content-Type', contentType)
context.res.setHeader('Content-Disposition', `attachment; filename="${targetFileName}"`)
context.res.setHeader('Content-Length', fileSize)
context.res.setHeader('Last-Modified', lastModified)
context.res.statusCode = 200
context.res.end(fileContents)

await asyncSend(req, res, realPath)
sendToTracker(getDownloadTrackData({
downloadDataType: path.dirname(fileName).split('/')[0],
downloadDataType: `${path.dirname(fileName).split('/')[0]}${req?.headers?.range ? ' (Partial)' : ''}`,
downloadFileName: fileName,
nbDownload: 1
}))
Expand Down
2 changes: 1 addition & 1 deletion views/data/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function Data({root, path = [], data = []}) {
<li key={entry.name}>
<Link
legacyBehavior
href={'./' + [...path, entry.name].join('/')}
href={encodeURI('./' + [...path, entry.name].join('/'))}
>
<a
target={entry.isDirectory ? '_self' : `file-${entry.name}`}
Expand Down
7 changes: 1 addition & 6 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5500,11 +5500,6 @@ [email protected]:
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==

mime@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7"
integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==

mimic-fn@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
Expand Down Expand Up @@ -6702,7 +6697,7 @@ semver@^7.2.1, semver@^7.3.4, semver@^7.3.5:
dependencies:
lru-cache "^6.0.0"

[email protected]:
[email protected], send@^0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==
Expand Down

0 comments on commit 83ba5fd

Please sign in to comment.