2018-02-14 10:12:46 -05:00
|
|
|
request = require 'request'
|
|
|
|
FileWriter = require('../../infrastructure/FileWriter')
|
2018-02-16 12:13:26 -05:00
|
|
|
_ = require "underscore"
|
|
|
|
urlValidator = require 'valid-url'
|
2018-02-21 06:19:21 -05:00
|
|
|
Settings = require 'settings-sharelatex'
|
2018-02-16 12:13:26 -05:00
|
|
|
|
|
|
|
UrlFetchFailedError = (message) ->
|
|
|
|
error = new Error(message)
|
|
|
|
error.name = 'UrlFetchFailedError'
|
|
|
|
error.__proto__ = UrlFetchFailedError.prototype
|
|
|
|
return error
|
|
|
|
UrlFetchFailedError.prototype.__proto__ = Error.prototype
|
|
|
|
|
|
|
|
InvalidUrlError = (message) ->
|
|
|
|
error = new Error(message)
|
|
|
|
error.name = 'InvalidUrlError'
|
|
|
|
error.__proto__ = InvalidUrlError.prototype
|
|
|
|
return error
|
|
|
|
InvalidUrlError.prototype.__proto__ = Error.prototype
|
|
|
|
|
2018-02-14 10:12:46 -05:00
|
|
|
module.exports = UrlAgent = {
|
2018-02-16 12:13:26 -05:00
|
|
|
UrlFetchFailedError: UrlFetchFailedError
|
|
|
|
InvalidUrlError: InvalidUrlError
|
|
|
|
|
2018-02-14 10:12:46 -05:00
|
|
|
sanitizeData: (data) ->
|
|
|
|
return {
|
2018-02-21 06:19:21 -05:00
|
|
|
url: @._prependHttpIfNeeded(data.url)
|
2018-02-14 10:12:46 -05:00
|
|
|
}
|
|
|
|
|
2018-06-01 10:16:27 -04:00
|
|
|
canCreate: (data) -> true
|
|
|
|
|
2018-05-29 05:07:31 -04:00
|
|
|
decorateLinkedFileData: (data, callback = (err, newData) ->) ->
|
|
|
|
return callback(null, data)
|
|
|
|
|
2018-05-24 06:29:37 -04:00
|
|
|
checkAuth: (project_id, data, current_user_id, callback = (error, allowed)->) ->
|
|
|
|
callback(null, true)
|
|
|
|
|
2018-02-14 10:12:46 -05:00
|
|
|
writeIncomingFileToDisk: (project_id, data, current_user_id, callback = (error, fsPath) ->) ->
|
2018-02-16 12:13:26 -05:00
|
|
|
callback = _.once(callback)
|
2018-02-21 06:19:21 -05:00
|
|
|
url = data.url
|
2018-02-16 12:13:26 -05:00
|
|
|
if !urlValidator.isWebUri(url)
|
2018-03-01 06:32:05 -05:00
|
|
|
return callback(new InvalidUrlError("invalid url: #{url}"))
|
|
|
|
url = UrlAgent._wrapWithProxy(url)
|
2018-02-14 10:12:46 -05:00
|
|
|
readStream = request.get(url)
|
2018-02-16 12:13:26 -05:00
|
|
|
readStream.on "error", callback
|
|
|
|
readStream.on "response", (response) ->
|
|
|
|
if 200 <= response.statusCode < 300
|
|
|
|
FileWriter.writeStreamToDisk project_id, readStream, callback
|
|
|
|
else
|
2018-03-01 06:32:05 -05:00
|
|
|
error = new UrlFetchFailedError("url fetch failed: #{url}")
|
2018-02-16 12:13:26 -05:00
|
|
|
error.statusCode = response.statusCode
|
|
|
|
callback(error)
|
|
|
|
|
|
|
|
handleError: (error, req, res, next) ->
|
|
|
|
if error instanceof UrlFetchFailedError
|
|
|
|
res.status(422).send(
|
|
|
|
"Your URL could not be reached (#{error.statusCode} status code). Please check it and try again."
|
|
|
|
)
|
|
|
|
else if error instanceof InvalidUrlError
|
|
|
|
res.status(422).send(
|
|
|
|
"Your URL is not valid. Please check it and try again."
|
|
|
|
)
|
|
|
|
else
|
|
|
|
next(error)
|
2018-02-21 06:19:21 -05:00
|
|
|
|
|
|
|
_prependHttpIfNeeded: (url) ->
|
|
|
|
if !url.match('://')
|
|
|
|
url = 'http://' + url
|
|
|
|
return url
|
|
|
|
|
|
|
|
_wrapWithProxy: (url) ->
|
|
|
|
# TODO: Consider what to do for Community and Enterprise edition?
|
|
|
|
if !Settings.apis?.linkedUrlProxy?.url?
|
|
|
|
throw new Error('no linked url proxy configured')
|
|
|
|
return "#{Settings.apis.linkedUrlProxy.url}?url=#{encodeURIComponent(url)}"
|
2018-05-21 05:12:41 -04:00
|
|
|
}
|