FileStoreHandler.coffee 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. logger = require("logger-sharelatex")
  2. fs = require("fs")
  3. request = require("request")
  4. settings = require("settings-sharelatex")
  5. oneMinInMs = 60 * 1000
  6. fiveMinsInMs = oneMinInMs * 5
  7. module.exports = FileStoreHandler =
  8. uploadFileFromDisk: (project_id, file_id, fsPath, callback)->
  9. fs.lstat fsPath, (err, stat)->
  10. if err?
  11. logger.err err:err, project_id:project_id, file_id:file_id, fsPath:fsPath, "error stating file"
  12. callback(err)
  13. if !stat.isFile()
  14. logger.log project_id:project_id, file_id:file_id, fsPath:fsPath, "tried to upload symlink, not contining"
  15. return callback(new Error("can not upload symlink"))
  16. logger.log project_id:project_id, file_id:file_id, fsPath:fsPath, "uploading file from disk"
  17. readStream = fs.createReadStream(fsPath)
  18. opts =
  19. method: "post"
  20. uri: FileStoreHandler._buildUrl(project_id, file_id)
  21. timeout:fiveMinsInMs
  22. writeStream = request(opts)
  23. readStream.pipe writeStream
  24. writeStream.on 'response', (response) ->
  25. if response.statusCode not in [200, 201]
  26. err = new Error("non-ok response from filestore for upload: #{response.statusCode}")
  27. logger.err {err, statusCode: response.statusCode}, "error uploading to filestore"
  28. callback(err)
  29. else
  30. callback(null)
  31. readStream.on "error", (err)->
  32. logger.err err:err, project_id:project_id, file_id:file_id, fsPath:fsPath, "something went wrong on the read stream of uploadFileFromDisk"
  33. callback err
  34. writeStream.on "error", (err)->
  35. logger.err err:err, project_id:project_id, file_id:file_id, fsPath:fsPath, "something went wrong on the write stream of uploadFileFromDisk"
  36. callback err
  37. getFileStream: (project_id, file_id, query, callback)->
  38. logger.log project_id:project_id, file_id:file_id, query:query, "getting file stream from file store"
  39. queryString = ""
  40. if query? and query["format"]?
  41. queryString = "?format=#{query['format']}"
  42. opts =
  43. method : "get"
  44. uri: "#{@_buildUrl(project_id, file_id)}#{queryString}"
  45. timeout:fiveMinsInMs
  46. headers: {}
  47. if query? and query['range']?
  48. rangeText = query['range']
  49. if rangeText && rangeText.match? && rangeText.match(/\d+-\d+/)
  50. opts.headers['range'] = "bytes=#{query['range']}"
  51. readStream = request(opts)
  52. readStream.on "error", (err) ->
  53. logger.err {err, project_id, file_id, query}, "error in file stream"
  54. callback(null, readStream)
  55. deleteFile: (project_id, file_id, callback)->
  56. logger.log project_id:project_id, file_id:file_id, "telling file store to delete file"
  57. opts =
  58. method : "delete"
  59. uri: @_buildUrl(project_id, file_id)
  60. timeout:fiveMinsInMs
  61. request opts, (err, response)->
  62. if err?
  63. logger.err err:err, project_id:project_id, file_id:file_id, "something went wrong deleting file from filestore"
  64. callback(err)
  65. copyFile: (oldProject_id, oldFile_id, newProject_id, newFile_id, callback)->
  66. logger.log oldProject_id:oldProject_id, oldFile_id:oldFile_id, newProject_id:newProject_id, newFile_id:newFile_id, "telling filestore to copy a file"
  67. opts =
  68. method : "put"
  69. json:
  70. source:
  71. project_id:oldProject_id
  72. file_id:oldFile_id
  73. uri: @_buildUrl(newProject_id, newFile_id)
  74. timeout:fiveMinsInMs
  75. request opts, (err)->
  76. if err?
  77. logger.err err:err, oldProject_id:oldProject_id, oldFile_id:oldFile_id, newProject_id:newProject_id, newFile_id:newFile_id, "something went wrong telling filestore api to copy file"
  78. callback(err)
  79. _buildUrl: (project_id, file_id)->
  80. return "#{settings.apis.filestore.url}/project/#{project_id}/file/#{file_id}"