RequestParser.coffee 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. module.exports = RequestParser =
  2. VALID_COMPILERS: ["pdflatex", "latex", "xelatex", "lualatex"]
  3. MAX_TIMEOUT: 300
  4. parse: (body, callback = (error, data) ->) ->
  5. response = {}
  6. if !body.compile?
  7. return callback "top level object should have a compile attribute"
  8. compile = body.compile
  9. compile.options ||= {}
  10. try
  11. response.compiler = @_parseAttribute "compiler",
  12. compile.options.compiler,
  13. validValues: @VALID_COMPILERS
  14. default: "pdflatex"
  15. type: "string"
  16. response.timeout = @_parseAttribute "timeout",
  17. compile.options.timeout
  18. default: RequestParser.MAX_TIMEOUT
  19. type: "number"
  20. if response.timeout > RequestParser.MAX_TIMEOUT
  21. response.timeout = RequestParser.MAX_TIMEOUT
  22. response.timeout = response.timeout * 1000 # milliseconds
  23. response.resources = (@_parseResource(resource) for resource in (compile.resources or []))
  24. rootResourcePath = @_parseAttribute "rootResourcePath",
  25. compile.rootResourcePath
  26. default: "main.tex"
  27. type: "string"
  28. response.rootResourcePath = RequestParser._sanitizePath(rootResourcePath)
  29. catch error
  30. return callback error
  31. callback null, response
  32. _parseResource: (resource) ->
  33. if !resource.path? or typeof resource.path != "string"
  34. throw "all resources should have a path attribute"
  35. if resource.modified?
  36. modified = new Date(resource.modified)
  37. if isNaN(modified.getTime())
  38. throw "resource modified date could not be understood: #{resource.modified}"
  39. if !resource.url? and !resource.content?
  40. throw "all resources should have either a url or content attribute"
  41. if resource.content? and typeof resource.content != "string"
  42. throw "content attribute should be a string"
  43. if resource.url? and typeof resource.url != "string"
  44. throw "url attribute should be a string"
  45. return {
  46. path: resource.path
  47. modified: modified
  48. url: resource.url
  49. content: resource.content
  50. }
  51. _parseAttribute: (name, attribute, options) ->
  52. if attribute?
  53. if options.validValues?
  54. if options.validValues.indexOf(attribute) == -1
  55. throw "#{name} attribute should be one of: #{options.validValues.join(", ")}"
  56. if options.type?
  57. if typeof attribute != options.type
  58. throw "#{name} attribute should be a #{options.type}"
  59. else
  60. return options.default if options.default?
  61. throw "Default not implemented"
  62. return attribute
  63. _sanitizePath: (path) ->
  64. # See http://php.net/manual/en/function.escapeshellcmd.php
  65. path.replace(/[\#\&\;\`\|\*\?\~\<\>\^\(\)\[\]\{\}\$\\\x0A\xFF\x00]/g, "")