UrlAgent.coffee 2.1 KB

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