UrlAgent.coffee 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. request = require 'request'
  2. FileWriter = require('../../infrastructure/FileWriter')
  3. _ = require "underscore"
  4. urlValidator = require 'valid-url'
  5. Settings = require 'settings-sharelatex'
  6. UrlFetchFailedError = (message) ->
  7. error = new Error(message)
  8. error.name = 'UrlFetchFailedError'
  9. error.__proto__ = UrlFetchFailedError.prototype
  10. return error
  11. UrlFetchFailedError.prototype.__proto__ = Error.prototype
  12. InvalidUrlError = (message) ->
  13. error = new Error(message)
  14. error.name = 'InvalidUrlError'
  15. error.__proto__ = InvalidUrlError.prototype
  16. return error
  17. InvalidUrlError.prototype.__proto__ = Error.prototype
  18. module.exports = UrlAgent = {
  19. UrlFetchFailedError: UrlFetchFailedError
  20. InvalidUrlError: InvalidUrlError
  21. sanitizeData: (data) ->
  22. return {
  23. url: @._prependHttpIfNeeded(data.url)
  24. }
  25. canCreate: (data) -> true
  26. decorateLinkedFileData: (data, callback = (err, newData) ->) ->
  27. return callback(null, data)
  28. checkAuth: (project_id, data, current_user_id, callback = (error, allowed)->) ->
  29. callback(null, true)
  30. writeIncomingFileToDisk: (project_id, data, current_user_id, callback = (error, fsPath) ->) ->
  31. callback = _.once(callback)
  32. url = data.url
  33. if !urlValidator.isWebUri(url)
  34. return callback(new InvalidUrlError("invalid url: #{url}"))
  35. url = UrlAgent._wrapWithProxy(url)
  36. readStream = request.get(url)
  37. readStream.on "error", callback
  38. readStream.on "response", (response) ->
  39. if 200 <= response.statusCode < 300
  40. FileWriter.writeStreamToDisk project_id, readStream, callback
  41. else
  42. error = new UrlFetchFailedError("url fetch failed: #{url}")
  43. error.statusCode = response.statusCode
  44. callback(error)
  45. handleError: (error, req, res, next) ->
  46. if error instanceof UrlFetchFailedError
  47. res.status(422).send(
  48. "Your URL could not be reached (#{error.statusCode} status code). Please check it and try again."
  49. )
  50. else if error instanceof InvalidUrlError
  51. res.status(422).send(
  52. "Your URL is not valid. Please check it and try again."
  53. )
  54. else
  55. next(error)
  56. _prependHttpIfNeeded: (url) ->
  57. if !url.match('://')
  58. url = 'http://' + url
  59. return url
  60. _wrapWithProxy: (url) ->
  61. # TODO: Consider what to do for Community and Enterprise edition?
  62. if !Settings.apis?.linkedUrlProxy?.url?
  63. throw new Error('no linked url proxy configured')
  64. return "#{Settings.apis.linkedUrlProxy.url}?url=#{encodeURIComponent(url)}"
  65. }