UrlAgent.coffee 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. decorateLinkedFileData: (data, callback = (err, newData) ->) ->
  26. return callback(null, data)
  27. checkAuth: (project_id, data, current_user_id, callback = (error, allowed)->) ->
  28. callback(null, true)
  29. writeIncomingFileToDisk: (project_id, data, current_user_id, callback = (error, fsPath) ->) ->
  30. callback = _.once(callback)
  31. url = data.url
  32. if !urlValidator.isWebUri(url)
  33. return callback(new InvalidUrlError("invalid url: #{url}"))
  34. url = UrlAgent._wrapWithProxy(url)
  35. readStream = request.get(url)
  36. readStream.on "error", callback
  37. readStream.on "response", (response) ->
  38. if 200 <= response.statusCode < 300
  39. FileWriter.writeStreamToDisk project_id, readStream, callback
  40. else
  41. error = new UrlFetchFailedError("url fetch failed: #{url}")
  42. error.statusCode = response.statusCode
  43. callback(error)
  44. handleError: (error, req, res, next) ->
  45. if error instanceof UrlFetchFailedError
  46. res.status(422).send(
  47. "Your URL could not be reached (#{error.statusCode} status code). Please check it and try again."
  48. )
  49. else if error instanceof InvalidUrlError
  50. res.status(422).send(
  51. "Your URL is not valid. Please check it and try again."
  52. )
  53. else
  54. next(error)
  55. _prependHttpIfNeeded: (url) ->
  56. if !url.match('://')
  57. url = 'http://' + url
  58. return url
  59. _wrapWithProxy: (url) ->
  60. # TODO: Consider what to do for Community and Enterprise edition?
  61. if !Settings.apis?.linkedUrlProxy?.url?
  62. throw new Error('no linked url proxy configured')
  63. return "#{Settings.apis.linkedUrlProxy.url}?url=#{encodeURIComponent(url)}"
  64. }