gina 0.1.1-alpha.21 → 0.1.1-alpha.210

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (369) hide show
  1. package/AUTHORS +2 -1
  2. package/LICENSE +1 -1
  3. package/README-4Contributors.md +30 -0
  4. package/README.md +210 -32
  5. package/bin/cli +166 -68
  6. package/bin/cli-debug +49 -18
  7. package/bin/cmd +40 -18
  8. package/bin/gina +48 -37
  9. package/framework/{v0.1.1-alpha.21/lib/inherits → v0.1.1-alpha.210}/LICENSE +1 -1
  10. package/framework/v0.1.1-alpha.210/VERSION +1 -0
  11. package/framework/{v0.1.1-alpha.21/core/asset/js/plugin/readme.md → v0.1.1-alpha.210/core/asset/plugin/README.md} +31 -9
  12. package/framework/v0.1.1-alpha.210/core/asset/plugin/dist/vendor/gina/css/gina.min.css +1 -0
  13. package/framework/v0.1.1-alpha.210/core/asset/plugin/dist/vendor/gina/css/gina.min.css.map +1 -0
  14. package/framework/v0.1.1-alpha.210/core/asset/plugin/dist/vendor/gina/html/toolbar.html +251 -0
  15. package/framework/{v0.1.1-alpha.21/core/asset/js/plugin/dist → v0.1.1-alpha.210/core/asset/plugin/dist/vendor/gina/js}/gina.js +4364 -3175
  16. package/framework/v0.1.1-alpha.210/core/asset/plugin/dist/vendor/gina/js/gina.min.js +764 -0
  17. package/framework/v0.1.1-alpha.210/core/asset/plugin/dist/vendor/gina/js/gina.min.js.map +8 -0
  18. package/framework/v0.1.1-alpha.210/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js +5 -0
  19. package/framework/v0.1.1-alpha.210/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.map +8 -0
  20. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/config.js +172 -79
  21. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/connectors/couchbase/index.js +373 -259
  22. package/framework/v0.1.1-alpha.210/core/connectors/couchbase/lib/connector.js +22 -0
  23. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/connectors/couchbase/lib/connector.v2.js +51 -51
  24. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/connectors/couchbase/lib/connector.v3.js +51 -51
  25. package/framework/v0.1.1-alpha.210/core/connectors/couchbase/lib/connector.v4.js +384 -0
  26. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/connectors/couchbase/lib/n1ql.js +3 -2
  27. package/framework/v0.1.1-alpha.210/core/connectors/couchbase/lib/session-store.js +22 -0
  28. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/connectors/couchbase/lib/session-store.v3.js +12 -12
  29. package/framework/v0.1.1-alpha.210/core/connectors/couchbase/lib/session-store.v4.js +361 -0
  30. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/controller/controller.js +921 -773
  31. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/dev/index.js +1 -1
  32. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/dev/lib/class.js +1 -1
  33. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/dev/lib/factory.js +2 -2
  34. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/gna.js +13 -9
  35. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/locales/README.md +5 -0
  36. package/framework/v0.1.1-alpha.210/core/locales/dist/region/en.json +5727 -0
  37. package/framework/v0.1.1-alpha.210/core/locales/dist/region/fr.json +11452 -0
  38. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/locales/index.js +2 -2
  39. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/locales/src/make.js +39 -41
  40. package/framework/v0.1.1-alpha.210/core/locales/src/resources/region.mapping.json +43 -0
  41. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/model/entity.js +87 -67
  42. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/model/index.js +16 -16
  43. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/model/template/entityFactory.js +1 -1
  44. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/model/template/index.js +17 -15
  45. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/index.js +1 -1
  46. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/file/package.json +1 -1
  47. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/intl/package.json +1 -1
  48. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/intl/src/main.js +5 -5
  49. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/storage/package.json +1 -1
  50. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/storage/src/main.js +6 -5
  51. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/validator/package.json +1 -1
  52. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/validator/src/form-validator.js +403 -300
  53. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/validator/src/main.js +1368 -1314
  54. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/router.js +99 -90
  55. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/server.isaac.js +203 -180
  56. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/server.js +439 -238
  57. package/framework/v0.1.1-alpha.210/core/template/boilerplate/bundle/config/settings.json +12 -0
  58. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/boilerplate/bundle/config/settings.server.json +4 -4
  59. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/boilerplate/bundle/config/templates.json +4 -4
  60. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/boilerplate/bundle/controllers/controller.content.js +1 -1
  61. package/framework/v0.1.1-alpha.210/core/template/boilerplate/bundle/controllers/setup.js +111 -0
  62. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/boilerplate/bundle/index.js +13 -1
  63. package/framework/v0.1.1-alpha.210/core/template/boilerplate/bundle_templates/html/content/homepage.html +8 -0
  64. package/framework/v0.1.1-alpha.210/core/template/boilerplate/bundle_templates/html/includes/error-msg-noscript.html +11 -0
  65. package/framework/v0.1.1-alpha.210/core/template/boilerplate/bundle_templates/html/includes/error-msg-outdated-browser.html +8 -0
  66. package/framework/{v0.1.1-alpha.21/core/template/boilerplate/bundle_templates/html/layout → v0.1.1-alpha.210/core/template/boilerplate/bundle_templates/html/layouts}/main.html +10 -3
  67. package/framework/v0.1.1-alpha.210/core/template/command/gina.bat.tpl +8 -0
  68. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/command/gina.tpl +4 -4
  69. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/conf/env.json +11 -0
  70. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/conf/package.json +1 -1
  71. package/framework/v0.1.1-alpha.210/core/template/conf/statics.json +12 -0
  72. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/conf/templates.json +2 -2
  73. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/helpers/console.js +3 -3
  74. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/helpers/context.js +148 -7
  75. package/framework/v0.1.1-alpha.210/helpers/data/LICENSE +9 -0
  76. package/framework/v0.1.1-alpha.210/helpers/data/README.md +12 -0
  77. package/framework/v0.1.1-alpha.210/helpers/data/package.json +20 -0
  78. package/framework/v0.1.1-alpha.210/helpers/data/src/main.js +295 -0
  79. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/helpers/dateFormat.js +9 -7
  80. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/helpers/index.js +13 -8
  81. package/framework/v0.1.1-alpha.210/helpers/json/LICENSE +9 -0
  82. package/framework/v0.1.1-alpha.210/helpers/json/README.md +12 -0
  83. package/framework/{v0.1.1-alpha.21/helpers/plugins → v0.1.1-alpha.210/helpers/json}/package.json +2 -2
  84. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/helpers/json/src/main.js +28 -26
  85. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/helpers/path.js +176 -96
  86. package/framework/{v0.1.1-alpha.21/helpers/json → v0.1.1-alpha.210/helpers/plugins}/package.json +2 -2
  87. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/helpers/plugins/src/api-error.js +23 -23
  88. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/helpers/plugins/src/main.js +3 -3
  89. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/helpers/prototypes.js +46 -38
  90. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/helpers/task.js +21 -14
  91. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/helpers/text.js +2 -2
  92. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/archiver/package.json +1 -1
  93. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/archiver/src/dep/jszip.min.js +3 -3
  94. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/archiver/src/main.js +168 -168
  95. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/aliases.json +4 -1
  96. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/bundle/add.js +84 -27
  97. package/framework/v0.1.1-alpha.210/lib/cmd/bundle/arguments.json +7 -0
  98. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/bundle/help.txt +4 -2
  99. package/framework/v0.1.1-alpha.210/lib/cmd/bundle/list.js +176 -0
  100. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/bundle/remove.js +36 -27
  101. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/bundle/start.js +264 -46
  102. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/bundle/stop.js +93 -74
  103. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/env/add.js +44 -43
  104. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/env/list.js +23 -4
  105. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/env/remove.js +19 -19
  106. package/framework/{v0.1.1-alpha.21/lib/cmd/scope → v0.1.1-alpha.210/lib/cmd/env}/use.js +21 -1
  107. package/framework/v0.1.1-alpha.210/lib/cmd/framework/build.js +88 -0
  108. package/framework/v0.1.1-alpha.210/lib/cmd/framework/init.js +798 -0
  109. package/framework/v0.1.1-alpha.210/lib/cmd/framework/link-node-modules.js +116 -0
  110. package/framework/v0.1.1-alpha.210/lib/cmd/framework/link.js +114 -0
  111. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/framework/open.js +22 -1
  112. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/framework/restart.js +61 -26
  113. package/framework/v0.1.1-alpha.210/lib/cmd/framework/set.js +285 -0
  114. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/framework/start.js +46 -20
  115. package/framework/v0.1.1-alpha.210/lib/cmd/framework/status.js +141 -0
  116. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/framework/stop.js +47 -28
  117. package/framework/v0.1.1-alpha.210/lib/cmd/framework/tail.js +302 -0
  118. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/framework/version.js +15 -3
  119. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/helper.js +131 -18
  120. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/index.js +23 -23
  121. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/port/inc/scan.js +32 -16
  122. package/framework/v0.1.1-alpha.210/lib/cmd/port/list.js +462 -0
  123. package/framework/v0.1.1-alpha.210/lib/cmd/port/reset.js +429 -0
  124. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/project/add.js +147 -122
  125. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/project/arguments.json +2 -1
  126. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/project/build.js +28 -28
  127. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/project/list.js +19 -2
  128. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/project/remove.js +19 -17
  129. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/project/rename.js +11 -11
  130. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/protocol/set.js +256 -209
  131. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/scope/list.js +27 -8
  132. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/scope/remove.js +19 -19
  133. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/view/add.js +35 -10
  134. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/collection/package.json +1 -1
  135. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/collection/src/main.js +243 -242
  136. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/config.js +31 -30
  137. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cron/package.json +1 -1
  138. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cron/src/main.js +10 -9
  139. package/framework/v0.1.1-alpha.210/lib/domain/LICENSE +9 -0
  140. package/framework/v0.1.1-alpha.210/lib/domain/README.md +46 -0
  141. package/framework/v0.1.1-alpha.210/lib/domain/dist/public_suffix_list.dat +14186 -0
  142. package/framework/v0.1.1-alpha.210/lib/domain/package.json +20 -0
  143. package/framework/v0.1.1-alpha.210/lib/domain/src/main.js +442 -0
  144. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/generator/index.js +5 -5
  145. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/index.js +3 -2
  146. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210/lib/inherits}/LICENSE +1 -1
  147. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/inherits/README.md +2 -2
  148. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/inherits/package.json +3 -4
  149. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/inherits/src/main.js +3 -3
  150. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/logger/package.json +2 -2
  151. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/logger/src/containers/default/index.js +13 -2
  152. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/logger/src/containers/file/index.js +109 -14
  153. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/logger/src/containers/mq/index.js +12 -3
  154. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/logger/src/containers/mq/listener.js +16 -14
  155. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/logger/src/containers/mq/speaker.js +32 -3
  156. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/logger/src/helper.js +21 -1
  157. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/logger/src/main.js +36 -9
  158. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/math/index.js +9 -9
  159. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/merge/README.md +2 -2
  160. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/merge/package.json +1 -1
  161. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/merge/src/main.js +118 -91
  162. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/model.js +10 -10
  163. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/proc.js +87 -49
  164. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/routing/package.json +1 -1
  165. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/routing/src/main.js +313 -285
  166. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/session-store.js +6 -6
  167. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/shell.js +3 -3
  168. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/swig-filters/package.json +1 -1
  169. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/swig-filters/src/main.js +140 -119
  170. package/framework/v0.1.1-alpha.210/lib/url/README.md +0 -0
  171. package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/validator.js +2 -2
  172. package/framework/v0.1.1-alpha.210/package.json +14 -0
  173. package/package.json +37 -25
  174. package/resources/home/main.json +53 -4
  175. package/resources/home/settings.json +9 -0
  176. package/resources/home/user/extensions/logger/default/config.json +1 -1
  177. package/resources/package.json.template +29 -18
  178. package/script/lib.js +0 -0
  179. package/script/post_install.js +496 -139
  180. package/script/pre_install.js +489 -77
  181. package/services/.gna/67fdf1b224a2ed5597e63d4b64283834468e05e3.txt +0 -0
  182. package/services/.gna/arch +1 -0
  183. package/services/.gna/locals.json +14 -0
  184. package/services/.gna/platform +1 -0
  185. package/services/configure +6 -0
  186. package/services/env.json +18 -0
  187. package/services/manifest.json +30 -0
  188. package/services/package.json +11 -0
  189. package/services/src/proxy/config/app.json +6 -0
  190. package/services/src/proxy/config/routing.json +11 -0
  191. package/services/src/proxy/config/settings.json +9 -0
  192. package/services/src/proxy/config/settings.server.json +31 -0
  193. package/services/src/proxy/config/statics.json +3 -0
  194. package/services/src/proxy/controllers/controller.content.js +58 -0
  195. package/services/src/proxy/controllers/controller.js +30 -0
  196. package/{framework/v0.1.1-alpha.21/core/template/boilerplate/bundle → services/src/proxy}/controllers/setup.js +14 -14
  197. package/services/src/proxy/index.js +31 -0
  198. package/services/src/proxy/lib/domain/README.md +48 -0
  199. package/services/src/proxy/lib/domain/src/config/public_suffix_list.dat +14186 -0
  200. package/services/src/toolbar/config/app.json +6 -0
  201. package/services/src/toolbar/config/routing.json +11 -0
  202. package/{framework/v0.1.1-alpha.21/core/template/boilerplate/bundle → services/src/toolbar}/config/settings.json +0 -0
  203. package/services/src/toolbar/config/settings.server.json +30 -0
  204. package/services/src/toolbar/controllers/controller.content.js +39 -0
  205. package/services/src/toolbar/controllers/controller.js +30 -0
  206. package/services/src/toolbar/controllers/setup.js +111 -0
  207. package/services/src/toolbar/index.js +43 -0
  208. package/utils/helper.js +236 -185
  209. package/utils/prototypes.js +9 -9
  210. package/utils/prototypes.json_clone.js +70 -37
  211. package/doc/framework/cli/doc.json +0 -9
  212. package/doc/framework/index.md +0 -60
  213. package/framework/v0.1.1-alpha.21/VERSION +0 -1
  214. package/framework/v0.1.1-alpha.21/core/asset/js/plugin/dist/gina.js.map +0 -56
  215. package/framework/v0.1.1-alpha.21/core/asset/js/plugin/dist/gina.min.css +0 -1
  216. package/framework/v0.1.1-alpha.21/core/asset/js/plugin/dist/gina.min.css.map +0 -1
  217. package/framework/v0.1.1-alpha.21/core/asset/js/plugin/dist/gina.min.js +0 -736
  218. package/framework/v0.1.1-alpha.21/core/asset/js/plugin/dist/gina.min.js.map +0 -56
  219. package/framework/v0.1.1-alpha.21/core/asset/js/plugin/dist/gina.onload.min.js +0 -5
  220. package/framework/v0.1.1-alpha.21/core/asset/js/plugin/dist/gina.onload.min.js.map +0 -8
  221. package/framework/v0.1.1-alpha.21/core/connectors/couchbase/lib/connector.js +0 -20
  222. package/framework/v0.1.1-alpha.21/core/connectors/couchbase/lib/session-store.js +0 -21
  223. package/framework/v0.1.1-alpha.21/core/locales/dist/region/en.json +0 -9492
  224. package/framework/v0.1.1-alpha.21/core/locales/dist/region/fr.json +0 -9492
  225. package/framework/v0.1.1-alpha.21/core/locales/src/resources/region.mapping.json +0 -28
  226. package/framework/v0.1.1-alpha.21/core/template/boilerplate/bundle_templates/html/homepage.html +0 -4
  227. package/framework/v0.1.1-alpha.21/core/template/conf/statics.json +0 -10
  228. package/framework/v0.1.1-alpha.21/lib/cmd/bundle/arguments.json +0 -4
  229. package/framework/v0.1.1-alpha.21/lib/cmd/bundle/list.js +0 -129
  230. package/framework/v0.1.1-alpha.21/lib/cmd/framework/init.js +0 -514
  231. package/framework/v0.1.1-alpha.21/lib/cmd/framework/set.js +0 -161
  232. package/framework/v0.1.1-alpha.21/lib/cmd/framework/status.js +0 -72
  233. package/framework/v0.1.1-alpha.21/lib/cmd/framework/tail.js +0 -183
  234. package/framework/v0.1.1-alpha.21/lib/cmd/port/list.js +0 -176
  235. package/framework/v0.1.1-alpha.21/package.json +0 -14
  236. package/script/prepare_version.js +0 -429
  237. /package/{framework/v0.1.1-alpha.21/core/template/command/gina.bat.tpl → bin/gina.bat} +0 -0
  238. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/AUTHORS +0 -0
  239. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/asset/html/nolayout.html +0 -0
  240. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/asset/html/static.html +0 -0
  241. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/asset/img/android-chrome-192x192.png +0 -0
  242. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/asset/img/android-chrome-512x512.png +0 -0
  243. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/asset/img/apple-touch-icon.png +0 -0
  244. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/asset/img/favicon-16x16.png +0 -0
  245. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/asset/img/favicon-32x32.png +0 -0
  246. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/asset/img/favicon.ico +0 -0
  247. /package/framework/{v0.1.1-alpha.21/core/asset/js → v0.1.1-alpha.210/core/asset}/plugin/uuid.json +0 -0
  248. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/connectors/couchbase/lib/session-store.v2.js +0 -0
  249. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/controller/controller.framework.js +0 -0
  250. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/controller/index.js +0 -0
  251. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/deps/busboy/.travis.yml +0 -0
  252. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/deps/busboy/LICENSE +0 -0
  253. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/deps/busboy/README.md +0 -0
  254. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/deps/busboy/deps/encoding/encoding-indexes.js +0 -0
  255. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/deps/busboy/deps/encoding/encoding.js +0 -0
  256. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/deps/busboy/lib/main.js +0 -0
  257. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/deps/busboy/lib/types/multipart.js +0 -0
  258. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/deps/busboy/lib/types/urlencoded.js +0 -0
  259. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/deps/busboy/lib/utils.js +0 -0
  260. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/deps/busboy/package.json +0 -0
  261. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/deps/swig-client/swig-2.0.0.min.js +0 -0
  262. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/dev/lib/tools.js +0 -0
  263. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/locales/currency.json +0 -0
  264. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/locales/dist/language/en.json +0 -0
  265. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/locales/dist/language/fr.json +0 -0
  266. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/locales/src/resources/currency.csv +0 -0
  267. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/locales/src/resources/region.csv +0 -0
  268. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/mime.types +0 -0
  269. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/README.md +0 -0
  270. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/file/README.md +0 -0
  271. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/file/build.json +0 -0
  272. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/intl/README.md +0 -0
  273. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/intl/build.json +0 -0
  274. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/storage/README.md +0 -0
  275. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/storage/build.json +0 -0
  276. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/validator/README.md +0 -0
  277. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/plugins/lib/validator/build.json +0 -0
  278. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/server.express.js +0 -0
  279. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/status.codes +0 -0
  280. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/boilerplate/bundle/config/app.json +0 -0
  281. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/boilerplate/bundle/config/routing.json +0 -0
  282. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/boilerplate/bundle/controllers/controller.js +0 -0
  283. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/boilerplate/bundle_namespace/controllers/controller.js +0 -0
  284. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/boilerplate/bundle_public/css/default.css +0 -0
  285. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/boilerplate/bundle_public/css/vendor/readme.md +0 -0
  286. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/boilerplate/bundle_public/favicon.ico +0 -0
  287. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/boilerplate/bundle_public/js/vendor/readme.md +0 -0
  288. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/boilerplate/bundle_public/readme.md +0 -0
  289. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/boilerplate/bundle_templates/handlers/main.js +0 -0
  290. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/conf/manifest.json +0 -0
  291. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/conf/settings.json +0 -0
  292. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/error/client/json/401.json +0 -0
  293. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/error/client/json/403.json +0 -0
  294. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/error/client/json/404.json +0 -0
  295. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/error/server/html/50x.html +0 -0
  296. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/error/server/json/500.json +0 -0
  297. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/error/server/json/503.json +0 -0
  298. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/core/template/extensions/logger/config.json +0 -0
  299. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/helpers/plugins/README.md +0 -0
  300. /package/framework/{v0.1.1-alpha.21/helpers/json → v0.1.1-alpha.210/lib/archiver}/README.md +0 -0
  301. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/archiver/build.json +0 -0
  302. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/bundle/copy.js +0 -0
  303. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/bundle/cp.js +0 -0
  304. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/bundle/help.js +0 -0
  305. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/bundle/rename.js +0 -0
  306. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/bundle/restart.js +0 -0
  307. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/bundle/rm.js +0 -0
  308. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/bundle/status.js +0 -0
  309. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/env/get.js +0 -0
  310. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/env/help.js +0 -0
  311. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/env/help.txt +0 -0
  312. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/env/link-dev.js +0 -0
  313. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/env/rm.js +0 -0
  314. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/env/set.js +0 -0
  315. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/env/unset.js +0 -0
  316. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/framework/dot.js +0 -0
  317. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/framework/get.js +0 -0
  318. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/framework/help.js +0 -0
  319. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/framework/help.txt +0 -0
  320. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/framework/msg.json +0 -0
  321. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/framework/update.js +0 -0
  322. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/gina-dev.1.md +0 -0
  323. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/gina-framework.1.md +0 -0
  324. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/gina.1.md +0 -0
  325. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/msg.json +0 -0
  326. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/port/help.js +0 -0
  327. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/port/help.txt +0 -0
  328. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/port/set.js +0 -0
  329. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/project/help.js +0 -0
  330. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/project/help.txt +0 -0
  331. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/project/import.js +0 -0
  332. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/project/move.js +0 -0
  333. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/project/restart.js +0 -0
  334. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/project/rm.js +0 -0
  335. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/project/start.js +0 -0
  336. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/project/status.js +0 -0
  337. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/project/stop.js +0 -0
  338. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/protocol/help.js +0 -0
  339. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/protocol/help.txt +0 -0
  340. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/protocol/list.js +0 -0
  341. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/scope/help.js +0 -0
  342. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/scope/help.txt +0 -0
  343. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/scope/link-local.js +0 -0
  344. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/scope/rm.js +0 -0
  345. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/scope/set.js +0 -0
  346. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cmd/scope/unset.js +0 -0
  347. /package/framework/{v0.1.1-alpha.21/lib/cmd/env → v0.1.1-alpha.210/lib/cmd/scope}/use.js +0 -0
  348. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/collection/README.md +0 -0
  349. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/collection/build.json +0 -0
  350. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/cron/README.md +0 -0
  351. /package/framework/{v0.1.1-alpha.21/lib/archiver/README.md → v0.1.1-alpha.210/lib/domain/exemples/backend.js} +0 -0
  352. /package/framework/{v0.1.1-alpha.21/lib/routing/README.md → v0.1.1-alpha.210/lib/domain/exemples/frontend.html} +0 -0
  353. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/inherits/example/inheriting_eventemitter.js +0 -0
  354. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/inherits/example/protected_inheritance.js +0 -0
  355. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/inherits/example/simple_inheritance.js +0 -0
  356. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/inherits/example/super_attribute_overridden_by_child_on_init.js +0 -0
  357. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/logger/README.md +0 -0
  358. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/logger/src/containers/file/lib/logrotator/README.md +0 -0
  359. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/logger/src/containers/file/lib/logrotator/index.js +0 -0
  360. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/merge/example/merge.js +0 -0
  361. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/merge/example/merge_2_literal objects.js +0 -0
  362. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/merge/example/merge_and_preserve_first.js +0 -0
  363. /package/framework/{v0.1.1-alpha.21/lib/swig-filters → v0.1.1-alpha.210/lib/routing}/README.md +0 -0
  364. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/routing/build.json +0 -0
  365. /package/framework/{v0.1.1-alpha.21/lib/url → v0.1.1-alpha.210/lib/swig-filters}/README.md +0 -0
  366. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/url/index.js +0 -0
  367. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/url/mocks.json +0 -0
  368. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/url/routing.json +0 -0
  369. /package/framework/{v0.1.1-alpha.21 → v0.1.1-alpha.210}/lib/url/test.js +0 -0
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /*
3
3
  * This file is part of the gina package.
4
- * Copyright (c) 2009-2022 Rhinostone <contact@gina.io>
4
+ * Copyright (c) 2009-2023 Rhinostone <contact@gina.io>
5
5
  *
6
6
  * For the full copyright and license information, please view the LICENSE
7
7
  * file that was distributed with this source code.
@@ -19,13 +19,15 @@ var zlib = require('zlib');
19
19
  // var tls = require('tls');
20
20
  // var crypto = require('crypto');
21
21
 
22
- var lib = require('./../../lib') || require.cache[require.resolve('./../../lib')];
22
+ var lib = require('./../../lib') || require.cache[require.resolve('./../../lib')];
23
23
  var merge = lib.merge;
24
24
  var inherits = lib.inherits;
25
25
  var console = lib.logger;
26
26
  var Collection = lib.Collection;
27
- var routingUtils = lib.routing;
27
+ var routingLib = lib.routing;
28
28
  var swig = require('swig');
29
+ // Swig 2
30
+ // var swig = require('./../deps/swig-client/swig-2.0.0.min.js');
29
31
  var SwigFilters = lib.SwigFilters;
30
32
  var statusCodes = requireJSON( _( getPath('gina').core + '/status.codes') );
31
33
 
@@ -44,9 +46,9 @@ function SuperController(options) {
44
46
 
45
47
  //public
46
48
  this.name = 'SuperController';
47
- this.engine = {};
48
-
49
-
49
+ this.engine = {};
50
+
51
+
50
52
  var self = this;
51
53
  //private
52
54
  var local = {
@@ -68,16 +70,16 @@ function SuperController(options) {
68
70
  if ( typeof(SuperController.initialized) != 'undefined' ) {
69
71
  return getInstance()
70
72
  } else {
71
-
73
+
72
74
  SuperController.instance = self;
73
-
74
-
75
+
76
+
75
77
  if (local.options) {
76
78
  SuperController.instance._options = local.options;
77
79
  }
78
-
80
+
79
81
  SuperController.initialized = true;
80
-
82
+
81
83
  }
82
84
  }
83
85
 
@@ -85,46 +87,64 @@ function SuperController(options) {
85
87
  local.options = SuperController.instance._options = options;
86
88
  // 2022-03-07 Fix for none-developpement environnements (without cache)
87
89
  self._options = local.options;
88
-
90
+
89
91
  return SuperController.instance;
90
92
  }
91
93
 
92
94
  var hasViews = function() {
93
95
  return ( typeof(local.options.template) != 'undefined' ) ? true : false;
94
96
  }
95
-
97
+
96
98
  /**
97
99
  * isHttp2
98
100
  * Returns `true` if server configured for HTTP/2
99
- *
101
+ *
100
102
  * @returns {boolean} isHttp2
101
103
  */
102
104
  var isHttp2 = function() {
103
- var options = local.options;
105
+ var options = local.options;
104
106
  var protocolVersion = ~~options.conf.server.protocol.match(/\/(.*)$/)[1].replace(/\.\d+/, '');
105
107
  var httpLib = options.conf.server.protocol.match(/^(.*)\//)[1] + ( (protocolVersion >= 2) ? protocolVersion : '' );
106
-
107
-
108
+
109
+
108
110
  return /http2/.test(httpLib)
109
111
  }
112
+
113
+ var headersSent = function(res) {
114
+ var _res = ( typeof(res) != 'undefined' ) ? res : local.res;
115
+
116
+ if ( typeof(_res.headersSent) != 'undefined' ) {
117
+ return _res.headersSent
118
+ }
119
+
120
+ if (
121
+ typeof(_res.stream) != 'undefined'
122
+ && typeof(_res.stream.headersSent) != 'undefined'
123
+ && _res.stream.headersSent != 'null'
124
+ ) {
125
+ return true
126
+ }
127
+
128
+ return false;
129
+ }
110
130
  /**
111
131
  * isSecured
112
132
  * Returns `true` if server configured to handle a HTTPS exchanges
113
- *
133
+ *
114
134
  * @returns {boolean} isSecured
115
135
  */
116
136
  var isSecured = function() {
117
137
  return /https/.test(local.options.conf.server.scheme)
118
138
  }
119
-
139
+
120
140
  this.getRequestObject = function() {
121
141
  return local.req;
122
142
  }
123
-
143
+
124
144
  this.getResponseObject = function() {
125
145
  return local.res;
126
146
  }
127
-
147
+
128
148
  this.getNextCallback = function() {
129
149
  return local.next;
130
150
  }
@@ -146,7 +166,7 @@ function SuperController(options) {
146
166
  local.options = SuperController.instance._options = options;
147
167
  local.options.renderingStack = (local.options.renderingStack) ? local.options.renderingStack : [];
148
168
  local.options.isRenderingCustomError = (local.options.isRenderingCustomError) ? local.options.isRenderingCustomError : false;
149
-
169
+
150
170
 
151
171
  // N.B.: Avoid setting `page` properties as much as possible from the routing.json
152
172
  // It will be easier for the framework if set from the controller.
@@ -169,12 +189,12 @@ function SuperController(options) {
169
189
  // var data = { page: { view: { title: "My Title"}}};
170
190
  // self.render(data)
171
191
  // }
172
-
192
+
173
193
  if ( typeof(options.conf.content.routing[options.rule].param) != 'undefined' ) {
174
194
  var str = 'page.'
175
195
  , p = options.conf.content.routing[options.rule].param
176
196
  ;
177
-
197
+
178
198
  for (var key in p) {
179
199
  if ( p.hasOwnProperty(key) && !/^(control)$/.test(key) ) {
180
200
  str += key + '.';
@@ -213,23 +233,23 @@ function SuperController(options) {
213
233
  , rule = local.options.rule
214
234
  , ext = 'html' // by default
215
235
  , isWithoutLayout = false // by default
216
- , namespace = local.options.namespace || '';
236
+ , namespace = local.options.namespace || '';
217
237
 
218
238
 
219
239
  if ( typeof(local.options.template) != 'undefined' && local.options.template ) {
220
- if (
221
- typeof(local.options.template.ext) != 'undefined'
222
- && local.options.template.ext
240
+ if (
241
+ typeof(local.options.template.ext) != 'undefined'
242
+ && local.options.template.ext
223
243
  && local.options.template.ext != ''
224
244
  ) {
225
245
  ext = local.options.template.ext
226
246
  }
227
-
247
+
228
248
  if ( !/\./.test(ext) ) {
229
249
  ext = '.' + ext;
230
250
  local.options.template.ext = ext
231
251
  }
232
-
252
+
233
253
  if (
234
254
  typeof(local.options.template.layout) == 'undefined'
235
255
  || /^false$/.test(local.options.template.layout)
@@ -238,27 +258,27 @@ function SuperController(options) {
238
258
  isWithoutLayout = true;
239
259
  }
240
260
  }
241
-
242
-
261
+
262
+
243
263
  if ( hasViews() ) {
244
264
 
245
265
  if ( typeof(local.options.file) == 'undefined') {
246
266
  local.options.file = 'index'
247
267
  }
248
-
268
+
249
269
  if ( typeof(local.options.isWithoutLayout) == 'undefined' || !isWithoutLayout ) {
250
270
  local.options.isWithoutLayout = false;
251
271
  }
252
-
272
+
253
273
  rule = local.options.rule;
254
- namespace = local.options.namespace || 'default';
255
-
256
-
274
+ namespace = local.options.namespace || 'default';
275
+
276
+
257
277
  set('page.view.file', local.options.file);
258
278
  set('page.view.title', rule.replace(new RegExp('@' + options.conf.bundle), ''));
259
279
  set('page.view.namespace', namespace);
260
- }
261
-
280
+ }
281
+
262
282
 
263
283
  var ctx = getContext('gina');
264
284
  // new declaration && overrides
@@ -270,26 +290,31 @@ function SuperController(options) {
270
290
  "middleware" : ctx.middleware
271
291
  };
272
292
 
293
+ set('page.environment.allocated memory', (require('v8').getHeapStatistics().heap_size_limit / (1024 * 1024 * 1024)).toFixed(2) +' GB');
294
+
273
295
  set('page.environment.gina', version.number);
274
296
  set('page.environment.gina pid', GINA_PID);
275
297
  set('page.environment.nodejs', version.nodejs +' '+ version.platform +' '+ version.arch);
276
298
  set('page.environment.engine', options.conf.server.engine);//version.middleware
277
299
  set('page.environment.env', process.env.NODE_ENV);
278
300
  set('page.environment.envIsDev', self.isCacheless());
301
+ set('page.environment.scope', process.env.NODE_SCOPE);
302
+ set('page.environment.scopeIsLocal', process.env.NODE_SCOPE_IS_LOCAL);
279
303
  set('page.environment.date.now', new Date().format("isoDateTime"));
280
-
281
-
304
+
305
+
282
306
  var routing = local.options.conf.routing = ctx.config.envConf.routing; // all routes
283
- set('page.environment.routing', escape(JSON.stringify(routing))); // export for GFF
307
+ set('page.environment.routing', encodeRFC5987ValueChars(JSON.stringify(routing))); // export for GFF
284
308
  //reverseRouting
285
309
  var reverseRouting = local.options.conf.reverseRouting = ctx.config.envConf.reverseRouting; // all routes
286
- set('page.environment.reverseRouting', escape(JSON.stringify(reverseRouting))); // export for GFF
287
-
310
+ set('page.environment.reverseRouting', encodeRFC5987ValueChars(JSON.stringify(reverseRouting))); // export for GFF
311
+
288
312
  var forms = local.options.conf.forms = options.conf.content.forms // all forms
289
- set('page.environment.forms', escape(JSON.stringify(forms))); // export for GFF
313
+ set('page.environment.forms', encodeRFC5987ValueChars(JSON.stringify(forms))); // export for GFF
290
314
  set('page.forms', options.conf.content.forms);
291
-
315
+
292
316
  set('page.environment.hostname', ctx.config.envConf[options.conf.bundle][process.env.NODE_ENV].hostname);
317
+ set('page.environment.rootDomain', ctx.config.envConf[options.conf.bundle][process.env.NODE_ENV].rootDomain);
293
318
  set('page.environment.webroot', options.conf.server.webroot);
294
319
  set('page.environment.bundle', options.conf.bundle);
295
320
  set('page.environment.project', options.conf.projectName);
@@ -298,14 +323,14 @@ function SuperController(options) {
298
323
  set('page.environment.port', options.conf.server.port);
299
324
  set('page.environment.debugPort', options.conf.server.debugPort);
300
325
  set('page.environment.pid', process.pid);
301
-
302
-
326
+
327
+
303
328
  set('page.view.ext', ext);
304
329
  set('page.view.control', action);
305
330
  set('page.view.controller', local.options.controller.replace(options.conf.bundlesPath, ''), true);
306
331
  if (typeof (local.options.controlRequired) != 'undefined' ) {
307
332
  set('page.view.controlRequired', local.options.controlRequired);
308
- }
333
+ }
309
334
  set('page.view.method', local.options.method);
310
335
  set('page.view.namespace', namespace); // by default
311
336
  set('page.view.url', req.url);
@@ -314,12 +339,12 @@ function SuperController(options) {
314
339
  set('page.view.html.properties.mode.javascriptsDeferEnabled', local.options.template.javascriptsDeferEnabled);
315
340
  set('page.view.html.properties.mode.routeNameAsFilenameEnabled', local.options.template.routeNameAsFilenameEnabled);
316
341
  }
317
-
318
-
342
+
343
+
319
344
  var parameters = JSON.clone(req.getParams());
320
345
  parameters = merge(parameters, options.conf.content.routing[rule].param);
321
346
  // excluding default page properties
322
- delete parameters[0];
347
+ delete parameters[0];
323
348
  delete parameters.file;
324
349
  delete parameters.control;
325
350
  delete parameters.title;
@@ -329,7 +354,7 @@ function SuperController(options) {
329
354
 
330
355
  set('page.view.route', rule);
331
356
 
332
-
357
+
333
358
  var acceptLanguage = GINA_CULTURE; // by default : language-COUNTRY
334
359
  if ( typeof(req.headers['accept-language']) != 'undefined' ) {
335
360
  acceptLanguage = req.headers['accept-language']
@@ -348,8 +373,8 @@ function SuperController(options) {
348
373
 
349
374
  try {
350
375
  userLocales = locales.findOne({ lang: userLangCode }).content;
351
- } catch (err) {
352
- //var defaultRegion = (local.options.conf.content.settings.region) ? local.options.conf.content.settings.region.shortCode
376
+ } catch (err) {
377
+ //var defaultRegion = (local.options.conf.content.settings.region) ? local.options.conf.content.settings.region.shortCode
353
378
  console.warn('language code `'+ userLangCode +'` not handled by current locales setup: replacing by default: `'+ local.options.conf.content.settings.region.shortCode +'`');
354
379
  userLocales = locales.findOne({ lang: local.options.conf.content.settings.region.shortCode }).content // by default
355
380
  }
@@ -359,7 +384,7 @@ function SuperController(options) {
359
384
 
360
385
  // user locale
361
386
  options.conf.locale = new Collection(userLocales).findOne({ short: userCountryCode }) || {};
362
-
387
+
363
388
  //set('page.date.now', new Date().format("isoDateTime"));
364
389
  if ( typeof(options.conf.locale) == 'undefined' || !options.conf.locale ) {
365
390
  options.conf.locale = {}
@@ -370,21 +395,21 @@ function SuperController(options) {
370
395
  set('page.view.locale', options.conf.locale);
371
396
  set('page.view.lang', userCulture);
372
397
  }
373
-
398
+
374
399
  if ( !getContext('isProxyHost') ) {
375
400
  var isProxyHost = ( typeof(req.headers.host) != 'undefined' && local.options.conf.server.scheme +'://'+ req.headers.host != local.options.conf.hostname || typeof(req.headers[':authority']) != 'undefined' && local.options.conf.server.scheme +'://'+ req.headers[':authority'] != local.options.conf.hostname ) ? true : false;
376
401
  setContext('isProxyHost', isProxyHost);
377
402
  }
378
-
403
+
379
404
  //TODO - detect when to use swig
380
405
  var dir = null;
381
406
  if (local.options.template || self.templates) {
382
407
  dir = local.options.template.templates || self.templates;
383
-
408
+
384
409
  var swigOptions = {
385
410
  autoescape : ( typeof(local.options.autoescape) != 'undefined') ? local.options.autoescape : false,
386
411
  // `memory` is no working yet ... advanced rendering setup required
387
- //cache : (local.options.cacheless) ? false : 'memory'
412
+ // cache : (local.options.cacheless) ? false : 'memory'
388
413
  cache : false
389
414
  };
390
415
  if (dir) {
@@ -394,18 +419,18 @@ function SuperController(options) {
394
419
  local._swigOptions = JSON.clone(swigOptions);
395
420
  }
396
421
  swig.setDefaults(swigOptions);
397
- // used for self.engine.compile(tpl, swigOptions)(data)
422
+ // used for self.engine.compile(tpl, swigOptions)(swigData)
398
423
  swig.getOptions = function() {
399
424
  return local._swigOptions;
400
425
  }
401
426
  // preserve the same timezone as the system
402
427
  var defaultTZOffset = new Date().getTimezoneOffset();
403
428
  swig.setDefaultTZOffset(defaultTZOffset);
404
-
429
+
405
430
  self.engine = swig;
406
431
  }
407
432
  }
408
-
433
+
409
434
  this.renderWithoutLayout = function (data, displayToolbar) {
410
435
 
411
436
  // preventing multiple call of self.renderWithoutLayout() when controller is rendering from another required controller
@@ -414,7 +439,7 @@ function SuperController(options) {
414
439
  }
415
440
 
416
441
  local.options.isWithoutLayout = true;
417
-
442
+
418
443
  self.render(data, displayToolbar);
419
444
  }
420
445
 
@@ -444,47 +469,52 @@ function SuperController(options) {
444
469
  ) ? true : false;
445
470
  if (isRenderingCustomError)
446
471
  delete userData.isRenderingCustomError;
447
-
472
+
448
473
  var localOptions = (errOptions) ? errOptions : local.options;
449
474
  localOptions.renderingStack.push( self.name );
450
475
  // preventing multiple call of self.render() when controller is rendering from another required controller
451
476
  if ( localOptions.renderingStack.length > 1 && !isRenderingCustomError ) {
452
477
  return false
453
478
  }
454
-
455
-
479
+
480
+
456
481
  var data = null
457
482
  , layout = null
458
483
  , template = null
459
484
  , file = null
460
485
  , path = null
461
486
  , plugin = null
462
- , isWithoutLayout = (localOptions.isWithoutLayout) ? true : false
487
+ , isWithoutLayout = (localOptions.isWithoutLayout) ? true : false
463
488
  ;
464
-
489
+
465
490
  localOptions.debugMode = ( typeof(displayToolbar) == 'undefined' ) ? undefined : ( (/true/i.test(displayToolbar)) ? true : false ); // only active for dev env
466
-
491
+
467
492
  // specific override
468
493
  if (
469
494
  self.isCacheless()
470
- && typeof(local.req[ local.req.method.toLowerCase() ]) != 'undefined'
471
- && typeof(local.req[ local.req.method.toLowerCase() ].debug) != 'undefined'
495
+ && typeof(local.req[ local.req.method.toLowerCase() ]) != 'undefined'
496
+ && typeof(local.req[ local.req.method.toLowerCase() ].debug) != 'undefined'
472
497
  ) {
473
- localOptions.debugMode = ( /true/i.test(local.req[ local.req.method.toLowerCase() ].debug) ) ? true : false;
474
- } else if (
475
- self.isCacheless()
498
+ if ( !/^(true|false)$/i.test(local.req[ local.req.method.toLowerCase() ].debug) ) {
499
+ console.warn('Detected wrong value for `debug`: '+ local.req[ local.req.method.toLowerCase() ].debug);
500
+ console.warn('Switching `debug` to `true` as `cacheless` mode is enabled');
501
+ local.req[ local.req.method.toLowerCase() ].debug = true;
502
+ }
503
+ localOptions.debugMode = ( /^true$/i.test(local.req[ local.req.method.toLowerCase() ].debug) ) ? true : false;
504
+ } else if (
505
+ self.isCacheless()
476
506
  && hasViews()
477
- && !isWithoutLayout
478
- && localOptions.debugMode == undefined
507
+ && !isWithoutLayout
508
+ && localOptions.debugMode == undefined
479
509
  ) {
480
510
  localOptions.debugMode = true;
481
511
  } else if ( localOptions.debugMode == undefined ) {
482
512
  localOptions.debugMode = self.isCacheless()
483
513
  }
484
-
514
+
485
515
  try {
486
516
  data = getData();
487
-
517
+
488
518
  if (!userData) {
489
519
  userData = { page: { view: {}}}
490
520
  } else if ( userData && !userData['page']) {
@@ -502,7 +532,7 @@ function SuperController(options) {
502
532
  if ( isWithoutLayout ) {
503
533
  localTemplateConf = JSON.clone(localOptions.template);
504
534
  localTemplateConf.javascripts = new Collection(localTemplateConf.javascripts).find({ isCommon: false}, { isCommon: true, name: 'gina' });
505
- localTemplateConf.stylesheets = new Collection(localTemplateConf.stylesheets).find({ isCommon: false}, { isCommon: true, name: 'gina' });
535
+ localTemplateConf.stylesheets = new Collection(localTemplateConf.stylesheets).find({ isCommon: false}, { isCommon: true, name: 'gina' });
506
536
  }
507
537
  setResources(localTemplateConf);
508
538
  // Allowing file & ext override
@@ -512,13 +542,13 @@ function SuperController(options) {
512
542
  ) {
513
543
  data.page.view.file = localOptions.file = local.req.routing.param.file
514
544
  }
515
- if (
516
- typeof(local.req.routing.param.ext) != 'undefined'
545
+ if (
546
+ typeof(local.req.routing.param.ext) != 'undefined'
517
547
  && data.page.view.ext !== local.req.routing.param.ext
518
548
  ) {
519
549
  data.page.view.ext = localOptions.template.ext = local.req.routing.param.ext
520
550
  }
521
-
551
+
522
552
  file = (isRenderingCustomError) ? localOptions.file : data.page.view.file;
523
553
 
524
554
  // pre-compiling variables
@@ -527,13 +557,13 @@ function SuperController(options) {
527
557
  if (typeof(data.page.data) == 'undefined' ) {
528
558
  data.page.data = {}
529
559
  }
530
-
531
560
 
532
- if (
561
+
562
+ if (
533
563
  !local.options.isRenderingCustomError
534
- && typeof(data.page.data.status) != 'undefined'
535
- && !/^2/.test(data.page.data.status)
536
- && typeof(data.page.data.error) != 'undefined'
564
+ && typeof(data.page.data.status) != 'undefined'
565
+ && !/^2/.test(data.page.data.status)
566
+ && typeof(data.page.data.error) != 'undefined'
537
567
  ) {
538
568
  var statusCode = localOptions.conf.server.coreConfiguration.statusCodes;
539
569
  var errorObject = {
@@ -553,11 +583,16 @@ function SuperController(options) {
553
583
  // making path thru [namespace &] file
554
584
  if ( typeof(localOptions.namespace) != 'undefined' && localOptions.namespace ) {
555
585
  // excepted for custom paths
556
- if ( !/^(\.|\/|\\)/.test(file) )
586
+ if ( !/^(\.|\/|\\)/.test(file) ) {
587
+ var _ext = data.page.view.ext;
588
+ console.warn('file `'+ file +'` used in routing `'+ localOptions.rule +'` does not respect gina naming convention ! You should rename the file `'+ file + _ext +'` to `'+ ''+ file.replace(localOptions.namespace+'-', '') + _ext +'`');
589
+ console.warn('The reason you are getting this message is because your filename begeins with `<namespace>-`\n If you don\‘t want to rename, use template path like ./../'+ localOptions.namespace +'/'+file);
557
590
  file = ''+ file.replace(localOptions.namespace+'-', '');
558
-
591
+ }
592
+
593
+
559
594
  // means that rule name === namespace -> pointing to root namespace dir
560
- if (!file || file === localOptions.namespace) {
595
+ if (!file || file === localOptions.namespace) {
561
596
  file = 'index'
562
597
  }
563
598
  path = (isRenderingCustomError) ? _(file) : _(localOptions.template.html +'/'+ localOptions.namespace + '/' + file)
@@ -593,14 +628,14 @@ function SuperController(options) {
593
628
  dic['page.'+d] = data.page[d]
594
629
  }
595
630
 
596
-
631
+
597
632
 
598
633
  // please, do not start with a slashe when including...
599
634
  // ex.:
600
635
  // /html/inc/_partial.html (BAD)
601
636
  // html/inc/_partial.html (GOOD)
602
637
  // ./html/namespace/page.html (GOOD)
603
-
638
+
604
639
  if ( !fs.existsSync(path) ) {
605
640
  msg = 'could not open "'+ path +'"' +
606
641
  '\n1) The requested file does not exists in your templates/html (check your template directory). Can you find: '+path +
@@ -614,32 +649,32 @@ function SuperController(options) {
614
649
  self.throwError(err);
615
650
  return;
616
651
  }
617
-
618
- var isProxyHost = (
619
- typeof(local.req.headers.host) != 'undefined'
620
- && localOptions.conf.server.scheme +'://'+ local.req.headers.host != localOptions.conf.hostname
621
- || typeof(local.req.headers[':authority']) != 'undefined'
622
- && localOptions.conf.server.scheme +'://'+ local.req.headers[':authority'] != localOptions.conf.hostname
652
+
653
+ var isProxyHost = (
654
+ typeof(local.req.headers.host) != 'undefined'
655
+ && localOptions.conf.server.scheme +'://'+ local.req.headers.host != localOptions.conf.hostname
656
+ || typeof(local.req.headers[':authority']) != 'undefined'
657
+ && localOptions.conf.server.scheme +'://'+ local.req.headers[':authority'] != localOptions.conf.hostname
623
658
  ) ? true : false;
624
- // setup swig default filters
659
+ // setup swig default filters
625
660
  var filters = SwigFilters({
626
661
  options : JSON.clone(localOptions),
627
662
  isProxyHost : isProxyHost,
628
663
  throwError : self.throwError,
629
664
  req : local.req,
630
- res : local.res
665
+ res : local.res
631
666
  });
632
667
 
633
668
  try {
634
-
669
+
635
670
  // Extends default `length` filter
636
671
  swig.setFilter('length', filters.length);
637
672
 
638
-
673
+
639
674
 
640
675
  // Allows you to get a bundle web root
641
676
  swig.setFilter('getWebroot', filters.getWebroot);
642
-
677
+
643
678
  swig.setFilter('getUrl', filters.getUrl);
644
679
 
645
680
  } catch (err) {
@@ -651,10 +686,10 @@ function SuperController(options) {
651
686
  self.throwError(local.res, 500, new Error('template compilation exception encoutered: [ '+path+' ]\n'+(err.stack||err.message)));
652
687
  return;
653
688
  }
654
-
655
-
656
-
657
- var layoutPath = null
689
+
690
+
691
+
692
+ var layoutPath = null
658
693
  , assets = null
659
694
  , mapping = null
660
695
  , XHRData = null
@@ -665,26 +700,26 @@ function SuperController(options) {
665
700
  , isWithSwigLayout = null
666
701
  , isUsingGinaLayout = (!isWithoutLayout && typeof(localOptions.template.layout) != 'undefined' && fs.existsSync(local.options.template.layout)) ? true : false
667
702
  ;
668
-
669
- if ( isWithoutLayout || isUsingGinaLayout ) {
703
+
704
+ if ( isWithoutLayout || isUsingGinaLayout ) {
670
705
  layoutPath = (isWithoutLayout) ? localOptions.template.noLayout : localOptions.template.layout;
671
706
  // user layout override
672
- if ( isUsingGinaLayout && !isWithoutLayout ) {
707
+ if ( isUsingGinaLayout && !isWithoutLayout ) {
673
708
  layoutPath = localOptions.template.layout;
674
- }
709
+ }
675
710
  if (isWithoutLayout) {
676
711
  data.page.view.layout = layoutPath;
677
- }
712
+ }
678
713
  } else { // without layout case
679
-
714
+
680
715
  // by default
681
716
  layoutPath = localOptions.template.layout;
682
717
  if ( !/^\//.test(layoutPath)) {
683
718
  layoutPath = localOptions.template.templates +'/'+ layoutPath;
684
719
  }
685
720
  // default layout
686
- if (
687
- !isWithoutLayout && !fs.existsSync(layoutPath) && layoutPath == localOptions.template.templates +'/index.html'
721
+ if (
722
+ !isWithoutLayout && !fs.existsSync(layoutPath) && layoutPath == localOptions.template.templates +'/index.html'
688
723
  ) {
689
724
  console.warn('Layout '+ local.options.template.layout +' not found, replacing with `nolayout`: '+ localOptions.template.noLayout);
690
725
  layoutPath = localOptions.template.noLayout
@@ -703,57 +738,57 @@ function SuperController(options) {
703
738
  self.throwError(err);
704
739
  return;
705
740
  }
706
-
741
+
707
742
  }
708
-
709
-
743
+
744
+
710
745
  var isLoadingPartial = false;
711
- try {
746
+ try {
712
747
  assets = {assets:"${assets}"};
713
-
748
+
714
749
  /**
715
750
  * retrieve template & layout
716
- * */
717
- var tpl = null;
751
+ * */
752
+ var tpl = null;
718
753
  // tpl = fs.readFileSync(path).toString();
719
- // layout = fs.readFileSync(layoutPath).toString();
720
-
754
+ // layout = fs.readFileSync(layoutPath).toString();
755
+
721
756
  await Promise.all([
722
- readFile(layoutPath),
723
- readFile(path)
757
+ readFile(layoutPath),
758
+ readFile(path)
724
759
  ])
725
- .then(([_layout, _tpl]) => {
760
+ .then(([_layout, _tpl]) => {
726
761
  layout = _layout.toString();
727
762
  tpl = _tpl.toString();
728
763
  })
729
764
  .catch(error => {
730
- console.error(error.message);
731
- return;
732
- });
733
-
734
-
765
+ console.error(error.message);
766
+ return;
767
+ });
768
+
769
+
735
770
  // mappin conf
736
771
  mapping = { filename: path };
737
772
  if (isRenderingCustomError) {
738
773
  // TODO - Test if there is a block call `gina-error` in the layout & replace block name from tpl
739
-
774
+
740
775
  if ( !/\{\%(\s+extends|extends)/.test(tpl) ) {
741
776
  tpl = "\n{% extends '"+ layoutPath +"' %}\n" + tpl;
742
777
  }
743
778
  if (!/\{\% block content/.test(tpl)) {
744
779
  // TODO - test if lyout has <body>
745
780
  tpl = '{% block content %}<p>If you view this message you didn’t define a content block in your template.</p>{% endblock %}' + tpl;
746
- }
747
-
781
+ }
782
+
748
783
  tpl = tpl.replace(/\{\{ page\.content \}\}/g, '');
749
784
  }
750
-
785
+
751
786
  if ( isWithoutLayout || isWithSwigLayout) {
752
- layout = tpl;
787
+ layout = tpl;
753
788
  } else if (isUsingGinaLayout) {
754
789
  mapping = { filename: path };
755
790
  if ( /(\{\{|\{\{\s+)page\.content/.test(layout) ) {
756
-
791
+
757
792
  if ( /\{\%(\s+extends|extends)/.test(tpl) ) {
758
793
  err = new Error('You cannot use at the same time `page.content` in your layout `'+ layoutPath +'` while calling `extends` from your page or content `'+ path +'`. You have to choose one or the other');
759
794
  self.throwError(local.res, 500, err);
@@ -761,9 +796,9 @@ function SuperController(options) {
761
796
  }
762
797
  layout = layout.replace('{{ page.content }}', tpl);
763
798
  } else {
764
- layout = layout.replace(/\<\/body\>/i, '\t'+tpl+'\n</body>');
799
+ layout = layout.replace(/\<\/body\>/i, '\t'+tpl+'\n</body>');
765
800
  }
766
-
801
+
767
802
  } else {
768
803
  tpl = tpl.replace('{{ page.view.layout }}', data.page.view.layout);
769
804
  if (/\<\/body\>/i.test(layout)) {
@@ -771,178 +806,201 @@ function SuperController(options) {
771
806
  }
772
807
  else {
773
808
  layout += tpl;
774
- }
809
+ }
775
810
  }
776
-
811
+
777
812
  // precompilation needed in case of `extends` or in order to display the toolbar
778
- if ( hasViews() && self.isCacheless() || /\{\%(\s+extends|extends)/.test(layout) ) {
813
+ if ( hasViews() && self.isCacheless() || /\{\%(\s+extends|extends)/.test(layout) ) {
779
814
  layout = swig.compile(layout, mapping)(data);
780
815
  }
781
- //dic['page.content'] = layout;
782
-
816
+ //dic['page.content'] = layout;
817
+
783
818
  } catch(err) {
784
819
  err.stack = 'Exception, bad syntax or undefined data found: start investigating in '+ mapping.filename +'\n' + err.stack;
785
820
  self.throwError(local.res, 500, err);
786
821
  return
787
822
  }
788
-
789
- isLoadingPartial = (
790
- !/\<html/i.test(layout)
791
- || !/\<head/i.test(layout)
792
- || !/\<body/i.test(layout)
823
+
824
+ isLoadingPartial = (
825
+ !/\<html/i.test(layout)
826
+ || !/\<head/i.test(layout)
827
+ || !/\<body/i.test(layout)
793
828
  ) ? true : false;
794
-
829
+
795
830
  // if (isLoadingPartial) {
796
831
  // console.warn('----------------> loading partial `'+ path);
797
832
  // }
798
-
799
- isDeferModeEnabled = localOptions.template.javascriptsDeferEnabled || localOptions.conf.content.templates._common.javascriptsDeferEnabled || false;
800
-
833
+
834
+ isDeferModeEnabled = localOptions.template.javascriptsDeferEnabled || localOptions.conf.content.templates._common.javascriptsDeferEnabled || false;
835
+
801
836
  // iframe case - without HTML TAG
802
837
  if (!self.isXMLRequest() && !/\<html/.test(layout) ) {
803
838
  layout = '<html>\n\t<head></head>\n\t<body class="gina-iframe-body">\n\t\t'+ layout +'\n\t</body>\n</html>';
804
- }
805
-
839
+ }
840
+
806
841
  // adding stylesheets
807
842
  if (!isWithoutLayout && data.page.view.stylesheets && !/\{\{\s+(page\.view\.stylesheets)\s+\}\}/.test(layout) ) {
808
843
  layout = layout.replace(/\<\/head\>/i, '\n\t{{ page.view.stylesheets }}\n</head>')
809
844
  }
810
-
845
+
811
846
  if (hasViews() && isWithoutLayout) {
812
847
  // $.getScript(...)
813
848
  //var isProxyHost = ( typeof(local.req.headers.host) != 'undefined' && localOptions.conf.server.scheme +'://'+ local.req.headers.host != localOptions.conf.hostname || typeof(local.req.headers[':authority']) != 'undefined' && localOptions.conf.server.scheme +'://'+ local.req.headers[':authority'] != localOptions.conf.hostname ) ? true : false;
814
849
  //var hostname = (isProxyHost) ? localOptions.conf.hostname.replace(/\:\d+$/, '') : localOptions.conf.hostname;
815
-
816
-
817
-
850
+
851
+
852
+
818
853
  var scripts = data.page.view.scripts;
819
854
  scripts = scripts.replace(/\s+\<script/g, '\n<script');
820
-
855
+
821
856
  if (!isProxyHost) {
822
857
  var webroot = data.page.environment.webroot;
823
858
  scripts = scripts.replace(/src\=\"\/(.*)\"/g, 'src="'+ webroot +'$1"');
824
859
  //stylesheets = stylesheets.replace(/href\=\"\/(.*)\"/g, 'href="'+ webroot +'$1"')
825
860
  }
826
-
861
+
827
862
  // iframe case - without HTML TAG
828
- if (self.isXMLRequest() || !/\<html/.test(layout) ) {
829
- layout += scripts;
830
- //layout += stylesheets;
831
- }
832
-
863
+ if (self.isXMLRequest() || !/\<html/.test(layout) ) {
864
+ layout += scripts;
865
+ //layout += stylesheets;
866
+ }
867
+
833
868
  }
834
869
 
835
870
  // adding plugins
836
-
837
-
871
+ // means that we don't want GFF context or we already have it loaded
872
+ viewInfos = JSON.clone(data.page.view);
873
+ if ( !isWithoutLayout )
874
+ viewInfos.assets = assets;
875
+
838
876
  if (
839
- hasViews() && self.isCacheless() && !isWithoutLayout
840
- && localOptions.debugMode
841
- ||
842
- hasViews() && self.isCacheless() && !isWithoutLayout
843
- && typeof(localOptions.debugMode) == 'undefined'
844
- ||
845
- hasViews() && localOptions.debugMode
877
+ hasViews() && self.isCacheless() && !isWithoutLayout
878
+ && localOptions.debugMode
879
+ ||
880
+ hasViews() && self.isCacheless() && !isWithoutLayout
881
+ && typeof(localOptions.debugMode) == 'undefined'
882
+ ||
883
+ hasViews() && localOptions.debugMode
846
884
  ) {
847
885
 
848
886
  layout = ''
887
+ // + '{%- set ginaDataInspector = JSON.clone(page) -%}'
849
888
  + '{%- set ginaDataInspector = JSON.clone(page) -%}'
889
+ // + '{%- set ginaDataInspector = { view: {}, environment: { routing: {}}} -%}'
850
890
  + '{%- set ginaDataInspector.view.assets = {} -%}'
851
891
  + '{%- set ginaDataInspector.view.scripts = "ignored-by-toolbar" -%}'
852
892
  + '{%- set ginaDataInspector.view.stylesheets = "ignored-by-toolbar" -%}'
853
893
  + layout
854
894
  ;
855
-
895
+
856
896
  plugin = '\t'
857
897
  + '{# Gina Toolbar #}'
858
898
  + '{%- set userDataInspector = JSON.clone(page) -%}'
899
+ // + '{%- set userDataInspector = { view: {}, environment: { routing: {}}} -%}'
859
900
  + '{%- set userDataInspector.view.scripts = "ignored-by-toolbar" -%}'
860
901
  + '{%- set userDataInspector.view.stylesheets = "ignored-by-toolbar" -%}'
861
902
  + '{%- set userDataInspector.view.assets = '+ JSON.stringify(assets) +' -%}'
862
- + '{%- include "'+ getPath('gina').core +'/asset/js/plugin/src/gina/toolbar/toolbar.html" with { gina: ginaDataInspector, user: userDataInspector } -%}'
863
- + '{# END Gina Toolbar #}'
903
+ + '{%- include "'+ getPath('gina').core +'/asset/plugin/dist/vendor/gina/html/toolbar.html" with { gina: ginaDataInspector, user: userDataInspector } -%}'// jshint ignore:line
904
+ + '{# END Gina Toolbar #}'
864
905
  ;
865
-
906
+
866
907
 
867
908
  if (isWithoutLayout && localOptions.debugMode || localOptions.debugMode ) {
868
909
 
869
- XHRData = '\t<input type="hidden" id="gina-without-layout-xhr-data" value="'+ encodeURIComponent(JSON.stringify(data.page.data)) +'">\n\r';
870
-
871
- layout = layout.replace(/<\/body>/i, XHRData + '\n\t</body>');
910
+ if (self.isXMLRequest()) {
911
+ XHRData = '\t<input type="hidden" id="gina-without-layout-xhr-data" value="'+ encodeRFC5987ValueChars(JSON.stringify(data.page.data)) +'">\n\r';
912
+ XHRView = '\n<input type="hidden" id="gina-without-layout-xhr-view" value="'+ encodeRFC5987ValueChars(JSON.stringify(viewInfos)) +'">';
913
+ if ( /<\/body>/i.test(layout) ) {
914
+ layout = layout.replace(/<\/body>/i, XHRData + XHRView + '\n\t</body>');
915
+ } else {
916
+ // Popin case
917
+ // Fix added on 2023-01-25
918
+ layout += XHRData + XHRView + '\n\t'
919
+ }
920
+ }
921
+
922
+
872
923
  }
873
-
924
+
874
925
  if (self.isCacheless() || localOptions.debugMode ) {
875
926
  layout = layout.replace(/<\/body>/i, plugin + '\n\t</body>');
876
927
  }
877
-
928
+
878
929
  // adding javascripts
879
- layout.replace('{{ page.view.scripts }}', '');
930
+ layout.replace('{{ page.view.scripts }}', '');
880
931
  // placed in the HEAD excepted when rendering a partial or when `isDeferModeEnabled` == true
881
932
  if (isLoadingPartial) {
882
933
  layout += '\t{{ page.view.scripts }}';
883
934
  } else {
884
935
  if ( isDeferModeEnabled ) {
885
936
  layout = layout.replace(/\<\/head\>/i, '\t{{ page.view.scripts }}\n\t</head>');
886
- } else { // placed in the BODY
937
+ } else { // placed in the BODY
887
938
  layout = layout.replace(/\<\/body\>/i, '\t{{ page.view.scripts }}\n</body>');
888
939
  }
889
940
  }
890
-
941
+
891
942
  // ginaLoader cannot be deferred
892
943
  if ( !localOptions.template.javascriptsExcluded || localOptions.template.javascriptsExcluded != '**' ) {
893
- layout = layout.replace(/\<\/head\>/i, '\t'+ localOptions.template.ginaLoader +'\n</head>');
944
+ layout = layout.replace(/\<\/head\>/i, '\t'+ localOptions.template.ginaLoader +'\n</head>');
894
945
  }
895
946
 
896
947
  } else if ( hasViews() && self.isCacheless() && self.isXMLRequest() ) {
897
-
898
- if (isWithoutLayout) {
948
+
949
+ if (isWithoutLayout) {
899
950
  delete data.page.view.scripts;
900
- delete data.page.view.stylesheets;
951
+ delete data.page.view.stylesheets;
901
952
  }
902
953
  // means that we don't want GFF context or we already have it loaded
903
- viewInfos = JSON.clone(data.page.view);
904
- if ( !isWithoutLayout )
905
- viewInfos.assets = assets;
954
+ // viewInfos = JSON.clone(data.page.view);
955
+ // if ( !isWithoutLayout )
956
+ // viewInfos.assets = assets;
906
957
 
907
- XHRData = '\n<input type="hidden" id="gina-without-layout-xhr-data" value="'+ encodeURIComponent(JSON.stringify(data.page.data)) +'">';
908
- XHRView = '\n<input type="hidden" id="gina-without-layout-xhr-view" value="'+ encodeURIComponent(JSON.stringify(viewInfos)) +'">';
909
958
 
959
+ XHRData = '\n<input type="hidden" id="gina-without-layout-xhr-data" value="'+ encodeRFC5987ValueChars(JSON.stringify(data.page.data)) +'">';
960
+ XHRView = '\n<input type="hidden" id="gina-without-layout-xhr-view" value="'+ encodeRFC5987ValueChars(JSON.stringify(viewInfos)) +'">';
961
+ if ( /<\/body>/i.test(layout) ) {
962
+ layout = layout.replace(/<\/body>/i, XHRData + XHRView + '\n\t</body>');
963
+ } else {
964
+ // Popin case
965
+ // Fix added on 2023-01-25
966
+ layout += XHRData + XHRView + '\n\t'
967
+ }
910
968
 
911
- layout += XHRData + XHRView;
969
+ // layout += XHRData + XHRView;
912
970
 
913
971
  } else { // other envs like prod ...
914
-
972
+
915
973
  // adding javascripts
916
974
  // cleanup first
917
- layout.replace('{{ page.view.scripts }}', '');
975
+ layout.replace('{{ page.view.scripts }}', '');
918
976
  // placed in the HEAD excepted when rendering a partial or when `isDeferModeEnabled` == true
919
977
  // if (isLoadingPartial) {
920
978
  // layout += '\t{{ page.view.scripts }}';
921
979
  // } else {
922
980
  // if ( isDeferModeEnabled ) {
923
981
  // layout = layout.replace(/\<\/head\>/i, '\t{{ page.view.scripts }}\n\t</head>');
924
- // } else { // placed in the BODY
982
+ // } else { // placed in the BODY
925
983
  // layout = layout.replace(/\<\/body\>/i, '\t{{ page.view.scripts }}\n</body>');
926
984
  // }
927
985
  // }
928
-
986
+
929
987
  // // ginaLoader cannot be deferred
930
988
  // if ( !localOptions.template.javascriptsExcluded || localOptions.template.javascriptsExcluded != '**' ) {
931
- // layout = layout.replace(/\<\/head\>/i, '\t'+ localOptions.template.ginaLoader +'\n</head>');
989
+ // layout = layout.replace(/\<\/head\>/i, '\t'+ localOptions.template.ginaLoader +'\n</head>');
932
990
  // }
933
-
991
+
934
992
  // adding javascripts
935
993
  layout.replace('{{ page.view.scripts }}', '');
936
- if (isLoadingPartial) {
994
+ if (isLoadingPartial) {
937
995
  layout += '\t{{ page.view.scripts }}\n';
938
996
  if ( !localOptions.template.javascriptsExcluded || localOptions.template.javascriptsExcluded != '**' ) {
939
997
  layout += '\t'+ localOptions.template.ginaLoader +'\n';
940
998
  }
941
999
  } else {
942
- if ( isDeferModeEnabled && /\<\/head\>/i.test(layout) ) { // placed in the HEAD
1000
+ if ( isDeferModeEnabled && /\<\/head\>/i.test(layout) ) { // placed in the HEAD
943
1001
  layout = layout.replace(/\<\/head\>/i, '\t{{ page.view.scripts }}\n\t</head>');
944
-
945
- } else { // placed in the BODY
1002
+
1003
+ } else { // placed in the BODY
946
1004
  layout = layout.replace(/\<\/body\>/i, '\t{{ page.view.scripts }}\n</body>');
947
1005
  }
948
1006
  // ginaLoader cannot be deferred
@@ -951,20 +1009,20 @@ function SuperController(options) {
951
1009
  }
952
1010
  }
953
1011
  }
954
-
955
-
1012
+
1013
+
956
1014
  layout = whisper(dic, layout, /\{{ ([a-zA-Z.]+) \}}/g );
957
1015
  dic['page.content'] = layout;
958
1016
  /**
959
1017
  // special case for template without layout in debug mode - dev only
960
1018
  if ( hasViews() && localOptions.debugMode && self.isCacheless() && !/\{\# Gina Toolbar \#\}/.test(layout) ) {
961
- try {
962
-
963
- layout = layout.replace(/<\/body>/i, plugin + '\n\t</body>');
1019
+ try {
1020
+
1021
+ layout = layout.replace(/<\/body>/i, plugin + '\n\t</body>');
964
1022
  layout = whisper(dic, layout, /\{{ ([a-zA-Z.]+) \}}/g );
965
1023
  //swig.invalidateCache();
966
- layout = swig.compile(layout, mapping)(data);
967
-
1024
+ layout = swig.compile(layout, mapping)(swigData);
1025
+
968
1026
 
969
1027
  } catch (err) {
970
1028
  filename = localOptions.template.html;
@@ -972,22 +1030,23 @@ function SuperController(options) {
972
1030
  self.throwError(local.res, 500, new Error('Compilation error encountered while trying to process template `'+ filename + '`\n'+(err.stack||err.message)));
973
1031
  return;
974
1032
  }
975
- }
1033
+ }
976
1034
  else if (hasViews() && localOptions.debugMode && self.isCacheless()) {
977
1035
  try {
978
1036
  //layout = whisper(dic, layout, /\{{ ([a-zA-Z.]+) \}}/g );
979
- layout = swig.compile(layout, mapping)(data);
1037
+ layout = swig.compile(layout, mapping)(swigData);
980
1038
  } catch (err) {
981
1039
  filename = localOptions.template.html;
982
1040
  filename += ( typeof(data.page.view.namespace) != 'undefined' && data.page.view.namespace != '' && new RegExp('^' + data.page.view.namespace +'-').test(data.page.view.file) ) ? '/' + data.page.view.namespace + data.page.view.file.split(data.page.view.namespace +'-').join('/') + ( (data.page.view.ext != '') ? data.page.view.ext: '' ) : '/' + data.page.view.file+ ( (data.page.view.ext != '') ? data.page.view.ext: '' );
983
1041
  self.throwError(local.res, 500, new Error('Compilation error encountered while trying to process template `'+ filename + '`\n'+(err.stack||err.message)));
984
1042
  return;
985
1043
  }
986
- }
987
- */
988
-
1044
+ }
1045
+ */
1046
+
989
1047
 
990
- if ( !local.res.headersSent ) {
1048
+ // if ( !local.res.headersSent ) {
1049
+ if ( !headersSent() ) {
991
1050
  local.res.statusCode = ( typeof(localOptions.conf.server.coreConfiguration.statusCodes[data.page.data.status]) != 'undefined' ) ? data.page.data.status : 200; // by default
992
1051
  //catching errors
993
1052
  if (
@@ -1004,62 +1063,64 @@ function SuperController(options) {
1004
1063
  }
1005
1064
 
1006
1065
  local.res.setHeader('content-type', localOptions.conf.server.coreConfiguration.mime['html'] + '; charset='+ localOptions.conf.encoding );
1007
-
1066
+
1008
1067
  try {
1009
-
1068
+
1010
1069
  // escape special chars
1011
1070
  var blacklistRe = new RegExp('[\<\>]', 'g');
1012
1071
  // DO NOT REPLACE IT BY JSON.clone() !!!!
1013
-
1072
+
1014
1073
  data.page.data = JSON.parse(JSON.stringify(data.page.data).replace(blacklistRe, '\$&'));
1015
-
1074
+
1016
1075
  } catch (err) {
1017
1076
  filename = localOptions.template.html;
1018
1077
  filename += ( typeof(data.page.view.namespace) != 'undefined' && data.page.view.namespace != '' && new RegExp('^' + data.page.view.namespace +'-').test(data.page.view.file) ) ? '/' + data.page.view.namespace + data.page.view.file.split(data.page.view.namespace +'-').join('/') + ( (data.page.view.ext != '') ? data.page.view.ext: '' ) : '/' + data.page.view.file+ ( (data.page.view.ext != '') ? data.page.view.ext: '' );
1019
1078
  self.throwError(local.res, 500, new Error('Controller::render(...) compilation error encountered while trying to process template `'+ filename + '`\n' + (err.stack||err.message||err) ));
1020
1079
  return;
1021
1080
  }
1022
-
1023
-
1081
+
1082
+
1024
1083
  // Only available for http/2.0 for now
1025
1084
  if ( !self.isXMLRequest() && /http\/2/.test(localOptions.conf.server.protocol) ) {
1026
1085
  try {
1027
- // TODO - button in toolbar to empty url assets cache
1086
+ // TODO - button in toolbar to empty url assets cache
1028
1087
  if ( /** self.isCacheless() ||*/ typeof(localOptions.template.assets) == 'undefined' || typeof(localOptions.template.assets[local.req.url]) == 'undefined' ) {
1029
1088
  // assets string -> object
1030
1089
  //assets = self.serverInstance.getAssets(localOptions.conf, layout.toString(), swig, data);
1031
1090
  assets = self.serverInstance.getAssets(localOptions.conf, layout, swig, data);
1032
1091
  localOptions.template.assets = JSON.parse(assets);
1033
1092
  }
1034
-
1093
+
1035
1094
  // only for toolbar - TODO hasToolbar()
1036
1095
  if (
1037
1096
  self.isCacheless() && hasViews() && !isWithoutLayout
1038
1097
  || hasViews() && localOptions.debugMode
1039
- || self.isCacheless() && hasViews() && self.isXMLRequest()
1040
- ) {
1041
- layout = layout.replace('{"assets":"${assets}"}', assets );
1098
+ || self.isCacheless() && hasViews() && self.isXMLRequest()
1099
+ ) {
1100
+ layout = layout.replace('{"assets":"${assets}"}', assets );
1042
1101
  }
1043
-
1102
+
1044
1103
  } catch (err) {
1045
1104
  self.throwError(local.res, 500, new Error('Controller::render(...) calling getAssets(...) \n' + (err.stack||err.message||err) ));
1046
1105
  return;
1047
1106
  }
1048
1107
  }
1049
-
1050
- // Last compilation before rendering
1051
- layout = swig.compile(layout, mapping)(data);
1052
-
1053
- if ( !local.res.headersSent ) {
1108
+
1109
+ // Last compilation before rendering
1110
+ // Now we can use `data` instead of `swigData`
1111
+ layout = swig.compile(layout, mapping)(data);
1112
+
1113
+ if ( !headersSent() ) {
1054
1114
  if ( local.options.isRenderingCustomError ) {
1055
1115
  local.options.isRenderingCustomError = false;
1056
1116
  }
1117
+
1057
1118
  local.res.end(layout);
1058
- }
1059
-
1119
+ }
1120
+
1060
1121
  console.info(local.req.method +' ['+local.res.statusCode +'] '+ local.req.url);
1061
-
1062
- } else if (typeof(local.next) != 'undefined') {
1122
+
1123
+ } else if (typeof(local.next) != 'undefined') {
1063
1124
  // local.next();
1064
1125
  return local.next();
1065
1126
  } else {
@@ -1075,7 +1136,7 @@ function SuperController(options) {
1075
1136
  return;
1076
1137
  }
1077
1138
  }
1078
-
1139
+
1079
1140
 
1080
1141
  this.isXMLRequest = function() {
1081
1142
  return local.options.isXMLRequest;
@@ -1102,21 +1163,21 @@ function SuperController(options) {
1102
1163
  return false
1103
1164
  }
1104
1165
  if ( self.isProcessingError ) {
1105
- return;
1166
+ return;
1106
1167
  }
1107
1168
 
1108
1169
  var request = local.req;
1109
1170
  var response = local.res;
1110
1171
  var next = local.next || null;
1111
1172
  // var stream = null;
1112
- // if ( /http\/2/.test(local.options.conf.server.protocol) ) {
1113
- // stream = response.stream;
1173
+ // if ( /http\/2/.test(local.options.conf.server.protocol) ) {
1174
+ // stream = response.stream;
1114
1175
  // }
1115
1176
 
1116
1177
  if (!jsonObj) {
1117
1178
  jsonObj = {}
1118
1179
  }
1119
-
1180
+
1120
1181
  try {
1121
1182
  // just in case
1122
1183
  if ( typeof(jsonObj) == 'string') {
@@ -1126,7 +1187,7 @@ function SuperController(options) {
1126
1187
  // if( typeof(local.options) != "undefined" && typeof(local.options.charset) != "undefined" ){
1127
1188
  // response.setHeader("charset", local.options.charset);
1128
1189
  // }
1129
-
1190
+
1130
1191
 
1131
1192
  //catching errors
1132
1193
  if (
@@ -1151,7 +1212,7 @@ function SuperController(options) {
1151
1212
  response.setHeader('content-type', local.options.conf.server.coreConfiguration.mime['json'] + '; charset='+ local.options.conf.encoding)
1152
1213
  }
1153
1214
 
1154
- if ( !response.headersSent ) {
1215
+ if ( !headersSent(response) ) {
1155
1216
  console.info(request.method +' ['+ response.statusCode +'] '+ request.url);
1156
1217
 
1157
1218
  if ( local.options.isXMLRequest && self.isWithCredentials() ) {
@@ -1164,17 +1225,17 @@ function SuperController(options) {
1164
1225
  } else {
1165
1226
  len = data.length
1166
1227
  }
1167
-
1168
- if (!response.headersSent)
1228
+
1229
+ if (!headersSent(response))
1169
1230
  response.setHeader("content-length", len);
1170
-
1171
-
1231
+
1232
+
1172
1233
  // if (stream && !stream.destroyed) {
1173
1234
  // //stream.respond(header);
1174
1235
  // stream.end(data);
1175
1236
  // } else {
1176
1237
  response.write(data);
1177
-
1238
+
1178
1239
  // required to close connection
1179
1240
  setTimeout(function () {
1180
1241
  response.end();
@@ -1184,21 +1245,21 @@ function SuperController(options) {
1184
1245
  // Ignoring warning
1185
1246
  //console.warn(err);
1186
1247
  }
1187
-
1248
+
1188
1249
  if ( next ) {
1189
1250
  next()
1190
1251
  }
1191
1252
  }, 200);
1192
-
1193
-
1194
-
1253
+
1254
+
1255
+
1195
1256
  return // force completion
1196
1257
  // }
1197
-
1258
+
1198
1259
 
1199
1260
  } else { // normal case
1200
1261
  response.end(JSON.stringify(jsonObj));
1201
- if (!response.headersSent) {
1262
+ if (!headersSent(response)) {
1202
1263
  try {
1203
1264
  response.headersSent = true;
1204
1265
  } catch(err) {
@@ -1207,9 +1268,9 @@ function SuperController(options) {
1207
1268
  }
1208
1269
  }
1209
1270
  if ( next ) {
1210
- next()
1271
+ return next()
1211
1272
  }
1212
-
1273
+
1213
1274
  return;
1214
1275
  }
1215
1276
  }
@@ -1239,7 +1300,7 @@ function SuperController(options) {
1239
1300
  local.res.setHeader('content-type', 'text/plain' + '; charset='+ local.options.conf.encoding);
1240
1301
  }
1241
1302
 
1242
- if ( !local.res.headersSent ) {
1303
+ if ( !headersSent() ) {
1243
1304
  console.info(local.req.method +' ['+local.res.statusCode +'] '+ local.req.url);
1244
1305
  local.res.end(content);
1245
1306
  try {
@@ -1308,7 +1369,7 @@ function SuperController(options) {
1308
1369
  * Get data
1309
1370
  *
1310
1371
  * @param {String} variable Data name to set
1311
- * @returns {Object | String} data Data object or String
1372
+ * @returns {Object | String} data Data object or String
1312
1373
  * */
1313
1374
  var get = function(variable) {
1314
1375
  return local.userData[variable]
@@ -1324,24 +1385,24 @@ function SuperController(options) {
1324
1385
  self.throwError(500, new Error('No views configuration found. Did you try to add views before using Controller::render(...) ? Try to run: gina view:add '+ options.conf.bundle +' @'+ options.conf.projectName));
1325
1386
  return;
1326
1387
  }
1327
-
1388
+
1328
1389
  var authority = ( typeof(local.req.headers['x-forwarded-proto']) != 'undefined' ) ? local.req.headers['x-forwarded-proto'] : local.options.conf.server.scheme;
1329
1390
  authority += '://'+ local.req.headers.host;
1330
1391
  var useWebroot = false;
1331
1392
  if ( !/^\/$/.test(local.options.conf.server.webroot) && local.options.conf.server.webroot.length > 0 && local.options.conf.hostname.replace(/\:\d+$/, '') == authority ) {
1332
1393
  useWebroot = true
1333
1394
  }
1334
-
1395
+
1335
1396
  var reURL = new RegExp('^'+ local.options.conf.server.webroot);
1336
1397
 
1337
1398
  var cssStr = '', jsStr = '';
1338
-
1399
+
1339
1400
  //Get css
1340
1401
  if( viewConf.stylesheets ) {
1341
1402
  cssStr = getNodeRes('css', viewConf.stylesheets, useWebroot, reURL)
1342
1403
  }
1343
1404
  //Get js
1344
- if( viewConf.javascripts ) {
1405
+ if( viewConf.javascripts ) {
1345
1406
  jsStr = getNodeRes('js', viewConf.javascripts, useWebroot, reURL)
1346
1407
  }
1347
1408
 
@@ -1362,7 +1423,7 @@ function SuperController(options) {
1362
1423
  * @private
1363
1424
  * */
1364
1425
  var getNodeRes = function(type, resArr, useWebroot, reURL) {
1365
-
1426
+
1366
1427
  var r = 0
1367
1428
  , rLen = resArr.length
1368
1429
  , obj = null
@@ -1370,7 +1431,7 @@ function SuperController(options) {
1370
1431
  ;
1371
1432
  switch(type){
1372
1433
  case 'css':
1373
- for (; r < rLen; ++r) {
1434
+ for (; r < rLen; ++r) {
1374
1435
  obj = resArr[r];
1375
1436
  if (useWebroot && !reURL.test(obj.url) ) {
1376
1437
  obj.url = local.options.conf.server.webroot + obj.url.substr(1);
@@ -1378,32 +1439,32 @@ function SuperController(options) {
1378
1439
  // TODO - add support for cdn
1379
1440
  if (!/\:\/\//.test(obj.url) ) {
1380
1441
  obj.url = local.options.conf.hostname + obj.url;
1381
- }
1382
-
1442
+ }
1443
+
1383
1444
  if (obj.media)
1384
- str += '\n\t\t<link href="'+ obj.url +'" media="'+ obj.media +'" rel="'+ obj.rel +'" type="'+ obj.type +'">';
1445
+ str += '\n\t\t<link href="'+ obj.url +'" media="'+ obj.media +'" rel="'+ obj.rel +'" type="'+ obj.type +'">';
1385
1446
  else
1386
- str += '\n\t\t<link href="'+ obj.url +'" rel="'+ obj.rel +'" type="'+ obj.type +'">';
1447
+ str += '\n\t\t<link href="'+ obj.url +'" rel="'+ obj.rel +'" type="'+ obj.type +'">';
1387
1448
  }
1388
-
1449
+
1389
1450
  return str;
1390
1451
  break;
1391
1452
 
1392
1453
  case 'js':
1393
1454
  var deferMode = (local.options.template.javascriptsDeferEnabled) ? ' defer' : '';
1394
-
1455
+
1395
1456
  for (; r < rLen; ++r) {
1396
1457
  obj = resArr[r];
1397
1458
  if (useWebroot && !reURL.test(obj.url) ) {
1398
1459
  obj.url = local.options.conf.server.webroot + obj.url.substr(1);
1399
1460
  }
1400
- // TODO - add support for cdn
1461
+ // TODO - add support for cdn
1401
1462
  if (!/\:\/\//.test(obj.url) ) {
1402
1463
  obj.url = local.options.conf.hostname + obj.url;
1403
1464
  }
1404
- str += '\n\t\t<script'+ deferMode +' type="'+ obj.type +'" src="'+ obj.url +'"></script>'
1465
+ str += '\n\t\t<script'+ deferMode +' type="'+ obj.type +'" src="'+ obj.url +'"></script>'
1405
1466
  }
1406
-
1467
+
1407
1468
  return str;
1408
1469
  break;
1409
1470
  }
@@ -1419,17 +1480,17 @@ function SuperController(options) {
1419
1480
  var getData = function() {
1420
1481
  return refToObj( local.userData )
1421
1482
  }
1422
-
1483
+
1423
1484
 
1424
1485
  var isValidURL = function(url){
1425
1486
  var re = /(http|ftp|https|sftp):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:\/~+#-]*[\w@?^=%&amp;\/~+#-])?/;
1426
1487
  return (re.test(url)) ? true : false
1427
1488
  }
1428
-
1489
+
1429
1490
  /**
1430
- * Set method - Override current method
1491
+ * Set method - Override current method
1431
1492
  * E.g.: in case of redirect, to force PUT to GET
1432
- *
1493
+ *
1433
1494
  * @param {string} requestMethod - GET, POST, PUT, DELETE
1434
1495
  */
1435
1496
  var localRequestMethod = null, localRequestMethodParams = null;
@@ -1438,75 +1499,75 @@ function SuperController(options) {
1438
1499
  if ( /http\/2/i.test(conf.server.protocolShort) ) {
1439
1500
  local.req.headers[':method'] = local.req.method.toUpperCase()
1440
1501
  }
1441
-
1502
+
1442
1503
  localRequestMethod = local.req.method = local.req.routing.method = requestMethod.toUpperCase();
1443
-
1504
+
1444
1505
  local.res.setHeader('access-control-allow-methods', localRequestMethod);
1445
-
1446
- return localRequestMethod;
1506
+
1507
+ return localRequestMethod;
1447
1508
  }
1448
-
1509
+
1449
1510
  this.getRequestMethod = function() {
1450
1511
  return localRequestMethod;
1451
1512
  }
1452
-
1513
+
1453
1514
  this.setRequestMethodParams = function(params) {
1454
1515
  localRequestMethodParams = local.req[local.req.method.toLowerCase()] = localRequestMethodParams = params
1455
1516
  }
1456
-
1517
+
1457
1518
  this.getRequestMethodParams = function() {
1458
- return (localRequestMethodParams) ? localRequestMethodParams : local.req[local.req.method.toLowerCase()]
1519
+ return (localRequestMethodParams) ? localRequestMethodParams : local.req[local.req.method.toLowerCase()]
1459
1520
  }
1460
-
1521
+
1461
1522
  /**
1462
1523
  * isStaticRoute
1463
1524
  * Trying to determine if url is a `statics` ressource
1464
- *
1525
+ *
1465
1526
  * @param {string} url
1466
1527
  * @param {string} method
1467
- *
1528
+ *
1468
1529
  * @returns {boolean} isStaticRoute
1469
1530
  */
1470
1531
  var isStaticRoute = function(url, method, bundle, env, conf) {
1471
-
1532
+
1472
1533
  if ( !/get/i.test(method) ) {
1473
1534
  return false
1474
1535
  }
1475
-
1536
+
1476
1537
  // priority to statics - this portion of code has been duplicated to Server.js
1477
-
1538
+
1478
1539
  var staticsArr = conf[bundle][env].publicResources;
1479
1540
  var staticProps = {
1480
1541
  firstLevel : '/' + url.split(/\//g)[1] + '/',
1481
1542
  // to be considered as a stativ content, url must content at least 2 caracters after last `.`: .js, .html are ok
1482
1543
  isStaticFilename : /(\.([A-Za-z0-9]+){2}|\/)$/.test(url)
1483
- };
1484
-
1544
+ };
1545
+
1485
1546
  // handle resources from public with webroot in url
1486
1547
  if ( staticProps.isStaticFilename && conf[bundle][env].server.webroot != '/' && staticProps.firstLevel == conf[bundle][env].server.webroot ) {
1487
1548
  var matchedFirstInUrl = url.replace(conf[bundle][env].server.webroot, '').match(/[A-Za-z0-9_-]+\/?/);
1488
1549
  if ( matchedFirstInUrl && matchedFirstInUrl.length > 0 ) {
1489
1550
  staticProps.firstLevel = conf[bundle][env].server.webroot + matchedFirstInUrl[0]
1490
- }
1551
+ }
1491
1552
  }
1492
-
1493
- if (
1494
- staticProps.isStaticFilename && staticsArr.indexOf(url) > -1
1495
- || staticProps.isStaticFilename && staticsArr.indexOf( url.replace(url.substr(url.lastIndexOf('/')+1), '') ) > -1
1553
+
1554
+ if (
1555
+ staticProps.isStaticFilename && staticsArr.indexOf(url) > -1
1556
+ || staticProps.isStaticFilename && staticsArr.indexOf( url.replace(url.substr(url.lastIndexOf('/')+1), '') ) > -1
1496
1557
  || staticProps.isStaticFilename && staticsArr.indexOf(staticProps.firstLevel) > -1
1497
1558
  ) {
1498
1559
  return true
1499
1560
  }
1500
-
1561
+
1501
1562
  return false;
1502
1563
  }
1503
1564
 
1504
1565
  /**
1505
1566
  * redirect
1506
1567
  *
1507
- * TODO - improve redirect based on `utils.routing`
1568
+ * TODO - improve redirect based on `lib.routing`
1508
1569
  * e.g.: self.redirect('project-get', { companyId: companyId, clientId: clientId, id: projectId }, true)
1509
- *
1570
+ *
1510
1571
  * How to avoid redirect inside popin context
1511
1572
  * N.B.: When you are in a popin context, add an `id` to your template tag so it can be ignored by the default PopinHandler
1512
1573
  * E.g.: id="delete-link" -> <a href="#" id="delete-link">delete</a>
@@ -1553,21 +1614,21 @@ function SuperController(options) {
1553
1614
  * `ignoreWebRoot` behaves the like set to `false` by default
1554
1615
  *
1555
1616
  * N.B.: Gina will tell browsers not to cache redirections if you are using `dev` environement
1556
- *
1617
+ *
1557
1618
  * Trobleshouting:
1558
1619
  * ---------------
1559
- *
1620
+ *
1560
1621
  * Redirecting to a popin from the controller while posting from a form
1561
1622
  * If this does not work, like doing a real redirect, this
1562
1623
  * only means that the ID you are using for the form might be
1563
1624
  * a duplicate one from the the main document !!!
1564
1625
  *
1565
- * @param {object|string} req|rule - Request Object or Rule/Route name
1626
+ * @param {object|string} req|rule|url - Request Object or Rule/Route name
1566
1627
  * @param {object|boolean} res|ignoreWebRoot - Response Object or Ignore WebRoot & start from domain root: /
1567
1628
  * @param {object} [params] TODO
1568
1629
  *
1569
1630
  * @callback [ next ]
1570
- * */
1631
+ * */
1571
1632
  this.redirect = function(req, res, next) {
1572
1633
  var conf = self.getConfig();
1573
1634
  var bundle = conf.bundle;
@@ -1579,15 +1640,15 @@ function SuperController(options) {
1579
1640
  var ignoreWebRoot = null, isRelative = false;
1580
1641
  var originalUrl = null;
1581
1642
  var method = null;
1582
- var originalMethod = null;
1643
+ var originalMethod = null;
1583
1644
 
1584
1645
  if ( typeof(req) === 'string' ) {
1585
1646
 
1586
1647
  // if ( typeof(res) == 'undefined') {
1587
1648
  // // nothing to do
1588
1649
  // ignoreWebRoot = false
1589
- // } else
1590
- if (typeof(res) === 'string' || typeof(res) === 'number' || typeof(res) === 'boolean') {
1650
+ // } else
1651
+ if (typeof(res) === 'string' || typeof(res) === 'number' || typeof(res) === 'boolean') {
1591
1652
  if ( /true|1/.test(res) ) {
1592
1653
  ignoreWebRoot = true
1593
1654
  } else if ( /false|0/.test(res) ) {
@@ -1608,26 +1669,26 @@ function SuperController(options) {
1608
1669
  ignoreWebRoot = false;
1609
1670
  }
1610
1671
  }
1611
-
1672
+
1612
1673
  }
1613
1674
 
1614
1675
  if ( req.substr(0,1) === '/') { // is relative (not checking if the URI is defined in the routing.json)
1615
1676
  // if (wroot.substr(wroot.length-1,1) == '/') {
1616
1677
  // wroot = wroot.substr(wroot.length-1,1).replace('/', '')
1617
1678
  // }
1618
-
1679
+
1619
1680
  if ( /^\//.test(req) && !ignoreWebRoot )
1620
1681
  req = req.substr(1);
1621
-
1682
+
1622
1683
  rte = ( ignoreWebRoot != null && ignoreWebRoot ) ? req : wroot + req;
1623
1684
  // cleaning url in case of ?param=value
1624
- originalUrl = rte;
1685
+ originalUrl = rte;
1625
1686
  rte = rte.replace(/\?(.*)/, '');
1626
-
1687
+
1627
1688
  req = local.req;
1628
- originalMethod = ( typeof(req.originalMethod) != 'undefined') ? req.originalMethod : req.method;
1629
- console.debug('[ BUNDLE ][ '+ local.options.conf.bundle +' ][ Controller ] trying to get route: ', rte, bundle, req.method);
1630
- if ( !ignoreWebRoot || !isStaticRoute(rte, req.method, bundle, env, ctx.config.envConf) && !ignoreWebRoot ) {
1689
+ originalMethod = ( typeof(req.originalMethod) != 'undefined') ? req.originalMethod : req.method;
1690
+ console.debug('[ BUNDLE ][ '+ local.options.conf.bundle +' ][ Controller ] trying to get route: ', rte, bundle, req.method);
1691
+ if ( !ignoreWebRoot || !isStaticRoute(rte, req.method, bundle, env, ctx.config.envConf) && !ignoreWebRoot ) {
1631
1692
  req.routing = lib.routing.getRouteByUrl(rte, bundle, req.method, req);
1632
1693
  // try alternative method
1633
1694
  if (!req.routing) {
@@ -1637,7 +1698,7 @@ function SuperController(options) {
1637
1698
  method = req.method = 'GET'
1638
1699
  }
1639
1700
  }
1640
-
1701
+
1641
1702
  //route = route = req.routing.name;
1642
1703
  } else {
1643
1704
  req.routing = {
@@ -1646,59 +1707,59 @@ function SuperController(options) {
1646
1707
  }
1647
1708
  }
1648
1709
  }
1649
-
1710
+
1650
1711
  res = local.res;
1651
1712
  next = local.next;
1652
1713
  isRelative = true;
1653
-
1714
+
1654
1715
  req.routing.param.path = rte
1655
1716
  } else if ( isValidURL(req) ) { // might be an URL
1656
1717
  rte = req;
1657
- originalUrl = rte;
1718
+ originalUrl = rte;
1658
1719
  rte = rte.replace(/\?(.*)/, '');
1659
-
1720
+
1660
1721
  req = local.req;
1661
1722
  res = local.res;
1662
1723
  next = local.next;
1663
-
1724
+
1664
1725
  req.routing.param.url = rte
1665
1726
  } else { // is by default a route name
1666
-
1727
+
1667
1728
  if ( /\@/.test(req) ) {
1668
1729
  var rteArr = req.split(/\//);
1669
1730
  if ( typeof(rteArr[1]) != 'undefined' )
1670
1731
  env = rteArr[1];
1671
-
1732
+
1672
1733
  rte = route = rteArr[0];
1673
1734
  rteArr = rteArr[0].split(/\@/);
1674
-
1735
+
1675
1736
  bundle = rteArr[1];
1676
-
1737
+
1677
1738
  } else {
1678
1739
  rte = route = ( new RegExp('^/'+conf.bundle+'-$').test(req) ) ? req : wroot.match(/[^/]/g).join('') +'-'+ req;
1679
1740
  }
1680
-
1681
-
1741
+
1742
+
1682
1743
  req = local.req;
1683
1744
  res = local.res;
1684
1745
  next = local.next;
1685
-
1746
+
1686
1747
  req.routing.param.route = routing[rte]
1687
- }
1688
-
1748
+ }
1749
+
1689
1750
  } else {
1690
- route = req.routing.param.route;
1751
+ route = req.routing.param.route;
1691
1752
  }
1692
-
1753
+
1693
1754
  if ( !originalMethod ) {
1694
1755
  originalMethod = ( typeof(req.originalMethod) != 'undefined') ? req.originalMethod : req.method;
1695
1756
  }
1696
-
1697
- var path = originalUrl || req.routing.param.path || '';
1757
+
1758
+ var path = originalUrl || req.routing.param.path || '';
1698
1759
  var url = req.routing.param.url;
1699
- var code = req.routing.param.code || 301;
1760
+ var code = req.routing.param.code || 301;
1700
1761
 
1701
- var keepParams = req.routing.param['keep-params'] || false;
1762
+ var keepParams = req.routing.param['keep-params'] || false;
1702
1763
 
1703
1764
  var condition = true; //set by default for url @ path redirect
1704
1765
 
@@ -1710,20 +1771,20 @@ function SuperController(options) {
1710
1771
 
1711
1772
  var isProxyHost = ( typeof(local.req.headers.host) != 'undefined' && local.options.conf.server.scheme +'://'+ local.req.headers.host != local.options.conf.hostname || typeof(local.req.headers[':authority']) != 'undefined' && local.options.conf.server.scheme +'://'+ local.req.headers[':authority'] != local.options.conf.hostname ) ? true : false;
1712
1773
  var hostname = (isProxyHost) ? ctx.config.envConf[bundle][env].hostname.replace(/\:\d+$/, '') : ctx.config.envConf[bundle][env].hostname;
1713
-
1774
+
1714
1775
  // if ( !/\:\d+$/.test(req.headers.host) )
1715
1776
  // hostname = hostname.replace(/\:\d+$/, '');
1716
1777
 
1717
1778
  if (route) { // will go with route first
1718
-
1779
+
1719
1780
  if ( /\,/.test(routing[route].url) ) {
1720
1781
  var paths = routing[route].url.split(/\,/g);
1721
1782
  path = (ignoreWebRoot) ? paths[0].replace(wroot, '') : paths[0];
1722
1783
  } else {
1723
1784
  path = (ignoreWebRoot) ? routing[route].url.replace(wroot, '') : routing[route].url;
1724
1785
  }
1725
-
1726
- if (bundle != conf.bundle) {
1786
+
1787
+ if (bundle != conf.bundle) {
1727
1788
  path = hostname + path;
1728
1789
  }
1729
1790
  } else if (url && !path) {
@@ -1737,59 +1798,60 @@ function SuperController(options) {
1737
1798
  // nothing to do, just ignoring
1738
1799
  //} else {
1739
1800
  } else if ( !path && typeof(isRelative) == 'undefined' ) {
1740
-
1801
+
1741
1802
  path = hostname + path
1742
1803
  //path = local.req.headers.host + path
1743
1804
  }
1744
-
1745
-
1746
1805
 
1747
- if (!local.res.headersSent) {
1748
-
1806
+
1807
+
1808
+ if (!headersSent()) {
1809
+
1749
1810
  // backing up oldParams
1750
1811
  var oldParams = local.req[originalMethod.toLowerCase()];
1751
- var requestParams = req[req.method.toLowerCase()] || {};
1812
+ var requestParams = req[req.method.toLowerCase()] || {};
1752
1813
  if ( typeof(requestParams) != 'undefined' && typeof(requestParams.error) != 'undefined' ) {
1753
1814
  var redirectError = requestParams.error;
1754
1815
  self.throwError(requestParams.error);
1755
1816
  return;
1756
1817
  }
1757
-
1758
- if (
1759
- !/GET/i.test(req.method)
1760
- ||
1761
- originalMethod && !/GET/i.test(originalMethod)
1762
- ) { // trying to redirect using the wrong method ?
1763
-
1818
+
1819
+ if (
1820
+ !/GET/i.test(req.method)
1821
+ ||
1822
+ originalMethod && !/GET/i.test(originalMethod)
1823
+ ) { // trying to redirect using the wrong method ?
1824
+
1764
1825
  console.warn(new Error('Your are trying to redirect using the wrong method: `'+ req.method+'`.\nThis can often occur while redirecting from a controller to another controller or from a bundle to another.\nA redirection is not permitted in this scenario.\nD\'ont panic :)\nSwitching request method to `GET` method instead.\n').message);
1765
1826
  method = local.req.method = self.setRequestMethod('GET', conf);
1766
- code = 303;
1827
+ code = 303;
1767
1828
  }
1768
-
1769
-
1829
+
1830
+ var inheritedDataIsNeeded = ( req.method.toLowerCase() == originalMethod.toLowerCase() ) ? false: true;
1831
+
1770
1832
  // merging new & olds params
1771
1833
  requestParams = merge(requestParams, oldParams);
1772
1834
  // remove session to prevent reaching the 2000 chars limit
1773
1835
  // if you need the session, you need to find another way to retrieve while in the next route
1774
- if ( typeof(requestParams.session) != 'undefined' ) {
1836
+ if ( typeof(requestParams.session) != 'undefined' ) {
1775
1837
  delete requestParams.session;
1776
1838
  }
1777
- if ( typeof(requestParams) != 'undefined' && requestParams.count() > 0 ) {
1839
+ if ( typeof(requestParams) != 'undefined' && requestParams.count() > 0 ) {
1778
1840
  //if ( typeof(requestParams.error) != 'undefined' )
1779
-
1841
+
1780
1842
  var inheritedData = null;
1781
1843
  if ( /\?/.test(path) ) {
1782
- inheritedData = '&inheritedData='+ encodeURIComponent(JSON.stringify(requestParams));
1844
+ inheritedData = '&inheritedData='+ encodeRFC5987ValueChars(JSON.stringify(requestParams));
1783
1845
  } else {
1784
- inheritedData = '?inheritedData='+ encodeURIComponent(JSON.stringify(requestParams));
1785
- }
1786
-
1846
+ inheritedData = '?inheritedData='+ encodeRFC5987ValueChars(JSON.stringify(requestParams));
1847
+ }
1848
+
1787
1849
  if ( inheritedData.length > 2000 ) {
1788
1850
  var error = new ApiError('Controller::redirect(...) exceptions: `inheritedData` reached 2000 chars limit', 424);
1789
1851
  self.throwError(error);
1790
1852
  return;
1791
1853
  }
1792
-
1854
+
1793
1855
  // if redirecting from a xhrRequest
1794
1856
  if ( self.isXMLRequest() ) {
1795
1857
  // `requestParams` should be stored in the session to avoid passing datas in clear
@@ -1803,21 +1865,26 @@ function SuperController(options) {
1803
1865
  redirectObj.location += inheritedData;
1804
1866
  }
1805
1867
  }
1806
-
1868
+
1807
1869
  self.renderJSON(redirectObj);
1808
1870
  return;
1809
1871
  }
1810
-
1811
- path += inheritedData;
1812
- }
1813
-
1872
+
1873
+ if (inheritedDataIsNeeded) {
1874
+ path += inheritedData;
1875
+ }
1876
+ }
1877
+
1814
1878
  var ext = 'html';
1815
1879
  res.setHeader('content-type', local.options.conf.server.coreConfiguration.mime[ext]);
1816
-
1817
- if (
1818
- typeof(local.res._headers) != 'undefined'
1819
- && typeof(local.res._headers['access-control-allow-methods']) != 'undefined'
1820
- && local.res._headers['access-control-allow-methods'] != req.method
1880
+
1881
+ var resHeaderACAM = res.getHeader('access-control-allow-methods');
1882
+ if (
1883
+ // typeof(local.res._headers) != 'undefined'
1884
+ // && typeof(local.res._headers['access-control-allow-methods']) != 'undefined'
1885
+ // && local.res._headers['access-control-allow-methods'] != req.method
1886
+ typeof(resHeaderACAM) != 'undefined'
1887
+ && resHeaderACAM != req.method
1821
1888
  ||
1822
1889
  !new RegExp(req.method, 'i').test( res.getHeader('access-control-allow-methods') )
1823
1890
  ) {
@@ -1825,11 +1892,11 @@ function SuperController(options) {
1825
1892
  }
1826
1893
  //path += '?query='+ JSON.stringify(self.getRequestMethodParams());
1827
1894
  local.req[req.method.toLowerCase()] = self.getRequestMethodParams() || {};
1828
-
1895
+
1829
1896
  var headInfos = {
1830
- 'location': path
1831
- };
1832
-
1897
+ 'location': path
1898
+ };
1899
+
1833
1900
  if (self.isCacheless()) {
1834
1901
  res.writeHead(code, merge(headInfos, {
1835
1902
  'cache-control': 'no-cache, no-store, must-revalidate', // preventing browsers from using cache
@@ -1838,24 +1905,26 @@ function SuperController(options) {
1838
1905
  }))
1839
1906
  } else {
1840
1907
  res.writeHead(code, headInfos)
1841
- }
1842
- // in case of query from another bundle waiting for a response
1843
- var redirectObject = JSON.stringify({ status: code, headers: headInfos });
1844
- res.end(redirectObject);
1908
+ }
1909
+ // in case of query from another bundle waiting for a response
1910
+ var redirectObject = JSON.stringify({ status: code, headers: headInfos });
1911
+
1845
1912
  try {
1913
+ res.end(redirectObject);
1846
1914
  local.res.headersSent = true;// done for the render() method
1847
1915
  } catch(err){
1848
1916
  // ignoring the warning
1917
+ // console.warn(err.stack);
1849
1918
  }
1850
-
1919
+
1851
1920
  console.info(local.req.method.toUpperCase() +' ['+code+'] '+ path);
1852
-
1921
+
1853
1922
  if ( typeof(next) != 'undefined' )
1854
1923
  next();
1855
1924
  else
1856
1925
  return;
1857
1926
  }
1858
-
1927
+
1859
1928
  }
1860
1929
  }
1861
1930
 
@@ -1896,16 +1965,19 @@ function SuperController(options) {
1896
1965
  })
1897
1966
  }
1898
1967
  }
1899
-
1968
+
1900
1969
  this.getBundleStatus = function(req, res, next) {
1970
+ var conf = self.getConfig();
1901
1971
  self.renderJSON({
1902
1972
  status: 200,
1903
1973
  isAlive: true,
1904
- message: 'I am alive !'
1974
+ message: 'I am alive !',
1975
+ // bundle: conf.bundle,
1976
+ // project: conf.projectName
1905
1977
  });
1906
1978
  }
1907
-
1908
- this.checkBundleStatus = async function(bundle, cb) {
1979
+
1980
+ this.checkBundleStatus = async function(bundle, cb) {
1909
1981
  var opt = self.getConfig('app').proxy[bundle];
1910
1982
  var route = lib.routing.getRoute('bundle-status@'+bundle);
1911
1983
  opt.method = 'GET';
@@ -1915,29 +1987,35 @@ function SuperController(options) {
1915
1987
  .then( function onQueryResponse(_status) {
1916
1988
  response = _status
1917
1989
  });
1918
-
1990
+
1919
1991
  if (cb) {
1920
1992
  cb(error, response);
1921
1993
  } else {
1922
1994
  return response;
1923
1995
  }
1924
1996
  }
1925
-
1997
+
1926
1998
  /**
1927
1999
  * downloadFromURL
1928
2000
  * Download from an URL
1929
2001
  * - attachment/inline
1930
2002
  * OR
1931
- * - locally: `Controller.store(target, cb)` must be called to store on `onComplete` event
1932
- *
2003
+ * - locally: `Controller.store(target, cb)` must be called to store on `onComplete` event
2004
+ *
2005
+ * - Will trigger on frontend : Failed to load resource: Frame load interrupted
2006
+ * because there is no `res.end()`: whitch is normal, we want to stay on the referrer page
2007
+ *
2008
+ * - To avoid this, add to your download link the attribute `data-gina-link`
2009
+ * This will convert the regular HTTP Request to an XML Request
2010
+ *
1933
2011
  * @param {string} url - eg.: https://upload.wikimedia.org/wikipedia/fr/2/2f/Firefox_Old_Logo.png
1934
2012
  * @param {object} [options]
1935
- *
1936
- *
2013
+ *
2014
+ *
1937
2015
  * */
1938
2016
  this.downloadFromURL = function(url, options) {
1939
-
1940
- var defaultOptions = {
2017
+
2018
+ var defaultOptions = {
1941
2019
  // file name i you want to rename the file
1942
2020
  file: null,
1943
2021
  fileSize: null,
@@ -1947,7 +2025,7 @@ function SuperController(options) {
1947
2025
  contentDisposition: 'attachment',
1948
2026
  // content-type (https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Configuring_server_MIME_types)
1949
2027
  contentType: 'application/octet-stream',
1950
-
2028
+
1951
2029
  agent: false,
1952
2030
  // set to false to ignore certificate verification
1953
2031
  rejectUnauthorized: true,
@@ -1957,9 +2035,9 @@ function SuperController(options) {
1957
2035
  keepAlive: true,
1958
2036
  headers: {}
1959
2037
  };
1960
-
2038
+
1961
2039
  var opt = ( typeof(options) != 'undefined' ) ? merge(options, defaultOptions) : defaultOptions;
1962
-
2040
+
1963
2041
  var requestOptions = {};
1964
2042
  for (var o in opt) {
1965
2043
  if ( !/(toLocalDir|contentDisposition|contentType|file)/.test(o) )
@@ -1968,130 +2046,135 @@ function SuperController(options) {
1968
2046
 
1969
2047
  // defining protocol & scheme
1970
2048
  var protocol = null;
1971
- var scheme = null;
1972
-
2049
+ var scheme = null;
2050
+
1973
2051
  if ( /\:\/\//.test(url) ) {
1974
2052
  scheme = url.match(/^\w+\:/)[0];
1975
2053
  scheme = scheme.substr(0, scheme.length-1);
1976
-
2054
+
1977
2055
  if ( !/^http/.test(scheme) ) {
1978
2056
  self.throwError(local.res, 500, new Error('[ '+ scheme +' ] Scheme not supported. Ref.: `http` or `https` only'));
1979
2057
  return;
1980
2058
  }
1981
-
1982
-
1983
-
2059
+
2060
+
2061
+
1984
2062
  } else { // by default
1985
2063
  scheme = 'http';
1986
2064
  }
1987
-
2065
+
1988
2066
  requestOptions.scheme = scheme +':';
1989
-
2067
+
1990
2068
  //defining port
1991
2069
  var port = url.match(/\:\d+\//) || null;
1992
2070
  if ( port != null ) {
1993
2071
  port = port[0].substr(1, port[0].length-2);
1994
- requestOptions.port = ~~port;
2072
+ requestOptions.port = ~~port;
1995
2073
  }
1996
-
2074
+
1997
2075
  // defining hostname & path
1998
2076
  var parts = url.replace(new RegExp( scheme + '\:\/\/'), '').split(/\//g);
1999
2077
  requestOptions.host = parts[0].replace(/\:\d+/, '');
2000
2078
  requestOptions.path = '/' + parts.splice(1).join('/');
2001
-
2002
-
2079
+
2080
+
2003
2081
  // extension and mime
2004
- var filename = url.split(/\//g).pop();
2082
+ var filename = url.split(/\//g).pop();
2005
2083
  if (!filename) {
2006
2084
  self.throwError(local.res, 500, new Error('Filename not found in url: `'+ url +'`'));
2007
2085
  return;
2008
2086
  }
2009
-
2010
-
2087
+
2088
+
2011
2089
  if ( !/\.\w+$/.test(filename) ) {
2012
2090
  self.throwError(local.res, 500, new Error('[ '+ filename +' ] extension not found.'));
2013
2091
  return;
2014
2092
  }
2015
-
2016
-
2093
+
2094
+
2017
2095
  // filename renaming
2018
2096
  if (opt.file)
2019
2097
  filename = opt.file;
2020
-
2098
+
2021
2099
  if ( opt.contentDisposition == 'attachment') {
2022
2100
  opt.contentDisposition += '; filename=' + filename;
2023
2101
  }
2024
-
2102
+
2025
2103
  var ext = filename.match(/\.\w+$/)[0].substr(1)
2026
2104
  , contentType = null
2027
2105
  , tmp = _(GINA_TMPDIR +'/'+ filename, true)
2028
2106
  ;
2029
-
2107
+
2030
2108
  if ( typeof(local.options.conf.server.coreConfiguration.mime[ext]) != 'undefined' ) {
2031
2109
 
2032
2110
  contentType = (opt.contentType != defaultOptions.contentType) ? opt.contentType : local.options.conf.server.coreConfiguration.mime[ext];
2033
-
2111
+
2034
2112
  } else { // extension not supported
2035
2113
  self.throwError(local.res, 500, new Error('[ '+ ext +' ] Extension not supported. Ref.: gina/core mime.types'));
2036
2114
  return;
2037
2115
  }
2038
-
2116
+
2039
2117
  // defining responseType
2040
2118
  requestOptions.headers['content-type'] = contentType;
2041
2119
  requestOptions.headers['content-disposition'] = opt.contentDisposition;
2042
-
2120
+
2043
2121
  var browser = require(''+ scheme);
2044
2122
  //console.debug('requestOptions: \n', JSON.stringify(requestOptions, null, 4));
2045
-
2046
- browser.get(requestOptions, function(response) {
2047
-
2048
- local.res.setHeader('content-type', contentType + '; charset='+ local.options.conf.encoding);
2049
- local.res.setHeader('content-disposition', opt.contentDisposition);
2050
- if (opt.fileSize) {
2051
- local.res.setHeader('content-length', opt.fileSize);
2052
- }
2053
- //local.res.setHeader('content-length', opt.fileSize);
2054
- // local.res.setHeader('cache-control', 'must-revalidate');
2055
- // local.res.setHeader('pragma', 'must-revalidate');
2056
-
2057
- // response.on('end', function onResponsePipeEnd(){
2058
- // self.renderJSON({ url: url});
2059
- // //local.res.end( Buffer.from(data) );
2060
- // //local.res.headersSent = true;
2061
-
2062
- // // if ( typeof(local.next) != 'undefined')
2063
- // // local.next();
2064
- // // else
2065
- // // return;
2066
- // });
2067
-
2068
- response.pipe(local.res);
2069
- });
2070
-
2071
- return;
2072
2123
 
2124
+ browser
2125
+ .get(requestOptions, function(response) {
2126
+
2127
+ local.res.setHeader('content-type', contentType + '; charset='+ local.options.conf.encoding);
2128
+ local.res.setHeader('content-disposition', opt.contentDisposition);
2129
+ if (opt.fileSize) {
2130
+ local.res.setHeader('content-length', opt.fileSize);
2131
+ }
2132
+ //local.res.setHeader('content-length', opt.fileSize);
2133
+ // local.res.setHeader('cache-control', 'must-revalidate');
2134
+ // local.res.setHeader('pragma', 'must-revalidate');
2135
+
2136
+
2137
+ response.pipe(local.res);
2138
+ })
2139
+ .on('error', function onDownloadError(err) {
2140
+ self.throwError(local.res, 500, err);
2141
+ });
2142
+
2143
+
2144
+
2145
+ // Will trigger on frontend : Failed to load resource: Frame load interrupted
2146
+ // because there is no `res.end()`: whitch is normal, we want to stay on the referrer page
2147
+
2148
+ // To avoid this, add to your download link the attribute `data-gina-link`
2149
+ // This will convert the regular HTTP Request to an XML Request
2073
2150
  }
2074
2151
 
2075
-
2152
+
2076
2153
  /**
2077
2154
  * Download to targeted filename.ext - Will create target if new
2078
2155
  * Use `cb` callback or `onComplete` event
2079
2156
  *
2157
+ * - Will trigger on frontend : Failed to load resource: Frame load interrupted
2158
+ * because there is no `res.end()`: whitch is normal, we want to stay on the referrer page
2159
+ *
2160
+ * - To avoid this, add to your download link the attribute `data-gina-link`
2161
+ * This will convert the regular HTTP Request to an XML Request
2162
+ *
2080
2163
  * @param {string} filename
2081
2164
  * @param {object} options
2082
2165
  **/
2083
2166
  this.downloadFromLocal = function(filename) {
2084
-
2085
- var file = filename.split(/\//g).pop();
2167
+
2168
+ var file = filename.split(/\//g).pop();
2086
2169
  var ext = file.split(/\./g).pop()
2087
2170
  , contentType = null
2088
2171
  ;
2089
-
2172
+
2090
2173
  if ( typeof(local.options.conf.server.coreConfiguration.mime[ext]) != 'undefined' ) {
2091
2174
 
2092
2175
  contentType = local.options.conf.server.coreConfiguration.mime[ext];
2093
2176
  local.res.setHeader('content-type', contentType);
2094
- local.res.setHeader('content-disposition', 'attachment; filename=' + file);
2177
+ local.res.setHeader('content-disposition', 'attachment; filename=' + file);
2095
2178
 
2096
2179
  var filestream = fs.createReadStream(filename);
2097
2180
  filestream.pipe(local.res);
@@ -2099,7 +2182,7 @@ function SuperController(options) {
2099
2182
  } else { // extension not supported
2100
2183
  self.throwError(local.res, 500, new Error('[ '+ ext +' ] Extension not supported. Ref.: gina/core mime.types'));
2101
2184
  return;
2102
- }
2185
+ }
2103
2186
  }
2104
2187
 
2105
2188
 
@@ -2122,17 +2205,17 @@ function SuperController(options) {
2122
2205
  * */
2123
2206
  this.store = async function(target, files, cb) {
2124
2207
 
2125
-
2208
+
2126
2209
  var start = function(target, files, cb) {
2127
-
2210
+
2128
2211
  if (arguments.length == 2 && typeof(arguments[1]) == 'function' ) {
2129
2212
  var cb = arguments[1];
2130
2213
  }
2131
-
2214
+
2132
2215
  if ( typeof(files) == 'undefined' || typeof(files) == 'function' ) {
2133
2216
  files = local.req.files
2134
2217
  }
2135
-
2218
+
2136
2219
  var uploadedFiles = [];
2137
2220
 
2138
2221
  if ( typeof(files) == 'undefined' || files.count() == 0 ) {
@@ -2155,25 +2238,25 @@ function SuperController(options) {
2155
2238
  self.emit('uploaded', folder)
2156
2239
  }
2157
2240
  } else {
2158
- // files list
2159
- var fileName = null;
2241
+ // files list
2242
+ var fileName = null;
2160
2243
  for (var len = files.length; i < len; ++i ){
2161
-
2162
- fileName = files[i].filename || files[i].originalFilename
2163
-
2244
+
2245
+ fileName = files[i].filename || files[i].originalFilename
2246
+
2164
2247
  list[i] = {
2165
2248
  source: files[i].path,
2166
2249
  target: _(uploadDir.toString() + '/' + fileName)
2167
2250
  };
2168
-
2169
- uploadedFiles[i] = {
2251
+
2252
+ uploadedFiles[i] = {
2170
2253
  file : fileName,
2171
- filename : list[i].target,
2254
+ filename : list[i].target,
2172
2255
  size : files[i].size,
2173
2256
  type : files[i].type,
2174
2257
  encoding : files[i].encoding
2175
2258
  };
2176
-
2259
+
2177
2260
  }
2178
2261
 
2179
2262
  movefiles(0, local.res, list, function (err) {
@@ -2279,7 +2362,7 @@ function SuperController(options) {
2279
2362
  } while (cert.fingerprint256 !== lastprint256);
2280
2363
 
2281
2364
  }*/
2282
-
2365
+
2283
2366
  };
2284
2367
 
2285
2368
  this.query = function() { // options, data, callback
@@ -2293,7 +2376,7 @@ function SuperController(options) {
2293
2376
  data = arguments[arguments.length-1]
2294
2377
  }
2295
2378
  // preventing multiple call of self.query() when controller is rendering from another required controller
2296
- if (
2379
+ if (
2297
2380
  typeof(local.options) != 'undefined'
2298
2381
  && typeof(local.options.renderingStack) != 'undefined'
2299
2382
  && local.options.renderingStack.length > 1
@@ -2301,22 +2384,23 @@ function SuperController(options) {
2301
2384
  return false
2302
2385
  }
2303
2386
  self.isProcessingError = false; // by default
2304
-
2387
+
2305
2388
  var queryData = {}
2306
2389
  , defaultOptions = local.query.options
2307
2390
  , path = options.path
2308
- , browser = null
2391
+ , browser = null
2309
2392
  ;
2310
2393
 
2311
2394
  // options must be used as a copy in case of multiple calls of self.query(options, ...)
2312
2395
  options = merge(JSON.clone(options), defaultOptions);
2313
-
2396
+ // options = merge(options, defaultOptions);
2397
+
2314
2398
  for (var o in options) {//cleaning
2315
2399
  if ( typeof(options[o]) == 'undefined' || options[o] == undefined) {
2316
2400
  delete options[o]
2317
2401
  }
2318
2402
  }
2319
-
2403
+
2320
2404
  if (self.isCacheless() || self.isLocalScope() ) {
2321
2405
  options.rejectUnauthorized = false;
2322
2406
  }
@@ -2329,23 +2413,14 @@ function SuperController(options) {
2329
2413
  self.emit('query#complete', err)
2330
2414
  }
2331
2415
 
2332
-
2333
2416
 
2334
- // if (arguments.length <3) {
2335
- // if ( typeof(data) == 'function') {
2336
- // var callback = data;
2337
- // var data = undefined;
2338
- // } else {
2339
- // callback = undefined;
2340
- // }
2341
- // }
2342
2417
  if ( typeof(data) != 'undefined' && data.count() > 0) {
2343
2418
 
2344
2419
  queryData = '?';
2345
2420
  // TODO - if 'application/json' && method == (put|post)
2346
2421
  if ( ['put', 'post'].indexOf(options.method.toLowerCase()) >-1 && /(text\/plain|application\/json|application\/x\-www\-form)/i.test(options.headers['content-type']) ) {
2347
2422
  // replacing
2348
- queryData = encodeURIComponent(JSON.stringify(data))
2423
+ queryData = encodeRFC5987ValueChars(JSON.stringify(data))
2349
2424
  //queryData = JSON.stringify(data)
2350
2425
 
2351
2426
  } else {
@@ -2357,12 +2432,12 @@ function SuperController(options) {
2357
2432
  if ( typeof(tmpData[d]) == 'object') {
2358
2433
  tmpData[d] = JSON.stringify(tmpData[d]);
2359
2434
  }
2360
- queryData += d + '=' + encodeURIComponent(tmpData[d]) + '&';
2435
+ queryData += d + '=' + encodeRFC5987ValueChars(tmpData[d]) + '&';
2361
2436
  }
2362
2437
 
2363
2438
  queryData = queryData.substring(0, queryData.length-1);
2364
2439
  queryData = queryData.replace(/\s/g, '%20');
2365
-
2440
+
2366
2441
  options.path += queryData;
2367
2442
  }
2368
2443
 
@@ -2370,7 +2445,7 @@ function SuperController(options) {
2370
2445
  queryData = ''
2371
2446
  }
2372
2447
 
2373
-
2448
+
2374
2449
  // Internet Explorer override
2375
2450
  if ( local.req != null && /msie/i.test(local.req.headers['user-agent']) ) {
2376
2451
  options.headers['content-type'] = 'text/plain';
@@ -2389,7 +2464,7 @@ function SuperController(options) {
2389
2464
 
2390
2465
  //you need this, even when empty.
2391
2466
  options.headers['content-length'] = queryData.length;
2392
-
2467
+
2393
2468
  // adding gina headers
2394
2469
  if ( local.req != null && typeof(local.req.ginaHeaders) != 'undefined' ) {
2395
2470
  // gina form headers
@@ -2405,7 +2480,7 @@ function SuperController(options) {
2405
2480
  ;
2406
2481
  // cleanup options.path
2407
2482
  if (/\:\/\//.test(options.path)) {
2408
-
2483
+
2409
2484
  var hArr = options.path.split(/^(https|http)\:\/\//);
2410
2485
  var domain = hArr[1] +'://';
2411
2486
  var host = hArr[2].split(/\//)[0];
@@ -2417,72 +2492,84 @@ function SuperController(options) {
2417
2492
  .replace(options.host, '')
2418
2493
  .replace(':'+port, '');
2419
2494
  }
2420
-
2495
+
2421
2496
  // retrieve protocol & scheme: if empty, take the bundles protocol
2422
2497
  protocol = options.protocol || ctx.gina.config.envConf[ctx.bundle][ctx.env].server.protocol;// bundle servers's protocol by default
2423
2498
  protocol = protocol.match(/[.a-z 0-9]+/ig)[0];
2424
2499
  scheme = options.scheme || ctx.gina.config.envConf[ctx.bundle][ctx.env].server.scheme;// bundle servers's scheme by default
2425
2500
  scheme = scheme.match(/[a-z 0-9]+/ig)[0];
2426
-
2501
+ // retrieve credentials
2502
+ if ( typeof(options.ca) == 'undefined' || ! options.ca ) {
2503
+ options.ca = ctx.gina.config.envConf[ctx.bundle][ctx.env].server.credentials.ca;
2504
+ }
2505
+
2427
2506
  //retrieving dynamic host, hostname & port
2428
2507
  if ( /\@/.test(options.hostname) ) {
2429
-
2508
+
2430
2509
  var bundle = ( options.hostname.replace(/(.*)\:\/\//, '') ).split(/\@/)[0];
2431
-
2510
+
2432
2511
  // No shorcut possible because conf.hostname might differ from user inputs
2433
2512
  options.host = ctx.gina.config.envConf[bundle][ctx.env].host.replace(/(.*)\:\/\//, '').replace(/\:\d+/, '');
2434
2513
  options.hostname = ctx.gina.config.envConf[bundle][ctx.env].hostname;
2435
2514
  options.port = ctx.gina.config.envConf[bundle][ctx.env].server.port;
2436
-
2515
+
2437
2516
  options.protocol = ctx.gina.config.envConf[bundle][ctx.env].server.protocol;
2438
2517
  options.scheme = ctx.gina.config.envConf[bundle][ctx.env].server.scheme;
2518
+
2519
+ // retrieve credentials
2520
+ if ( typeof(options.ca) == 'undefined' || ! options.ca ) {
2521
+ options.ca = ctx.gina.config.envConf[bundle][ctx.env].server.credentials.ca;
2522
+ }
2523
+
2439
2524
  // might be != from the bundle requesting
2440
- //options.protocol = ctx.gina.config.envConf[bundle][ctx.env].content.settings.server.protocol || ctx.gina.config.envConf[bundle][ctx.env].server.protocol;
2441
- //options.scheme = ctx.gina.config.envConf[bundle][ctx.env].content.settings.server.scheme || ctx.gina.config.envConf[bundle][ctx.env].server.scheme;
2525
+ //options.protocol = ctx.gina.config.envConf[bundle][ctx.env].content.settings.server.protocol || ctx.gina.config.envConf[bundle][ctx.env].server.protocol;
2526
+ //options.scheme = ctx.gina.config.envConf[bundle][ctx.env].content.settings.server.scheme || ctx.gina.config.envConf[bundle][ctx.env].server.scheme;
2442
2527
  }
2443
-
2528
+
2444
2529
  if ( typeof(options.protocol) == 'undefined' ) {
2445
2530
  options.protocol = protocol
2446
2531
  }
2447
2532
  if ( typeof(options.scheme) == 'undefined' ) {
2448
2533
  options.scheme = scheme
2449
2534
  }
2450
-
2451
-
2535
+
2536
+
2537
+
2538
+
2452
2539
  // reformating scheme
2453
2540
  if( !/\:$/.test(options.scheme) )
2454
2541
  options.scheme += ':';
2455
-
2456
- try {
2457
- options.queryData = queryData;
2542
+
2543
+ try {
2544
+ options.queryData = queryData;
2458
2545
  var protocolVersion = ~~options.protocol.match(/\/(.*)$/)[1].replace(/\.\d+/, '');
2459
2546
  var httpLib = options.protocol.match(/^(.*)\//)[1] + ( (protocolVersion >= 2) ? protocolVersion : '' );
2460
2547
  if ( !/http2/.test(httpLib) && /https/.test(options.scheme) ) {
2461
2548
  httpLib += 's';
2462
2549
  }
2463
-
2464
- browser = require(''+ httpLib);
2465
-
2550
+
2551
+ browser = require(''+ httpLib);
2552
+
2466
2553
  if ( /http2/.test(httpLib) ) {
2467
2554
  return handleHTTP2ClientRequest(browser, options, callback);
2468
2555
  } else {
2469
- return handleHTTP1ClientRequest(browser, options, callback);
2470
- }
2471
-
2472
-
2556
+ return handleHTTP1ClientRequest(browser, options, callback);
2557
+ }
2558
+
2559
+
2473
2560
  } catch(err) {
2474
2561
  if (callback) {
2475
2562
  return callback(err)
2476
2563
  }
2477
2564
  self.emit('query#complete', err)
2478
2565
  }
2479
-
2566
+
2480
2567
  }
2481
-
2568
+
2482
2569
  var handleHTTP1ClientRequest = function(browser, options, callback) {
2483
-
2570
+
2484
2571
  var altOpt = JSON.clone(options);
2485
-
2572
+
2486
2573
  altOpt.protocol = options.scheme;
2487
2574
  altOpt.hostname = options.host;
2488
2575
  altOpt.port = options.port;
@@ -2492,24 +2579,24 @@ function SuperController(options) {
2492
2579
  } catch(err) {
2493
2580
  self.emit('query#complete', err);
2494
2581
  }
2495
-
2582
+
2496
2583
  } else {
2497
2584
  console.warn('[ CONTROLLER ][ HTTP/1.0#query ] options.encKey not found !');
2498
2585
  }
2499
-
2586
+
2500
2587
  if ( typeof(altOpt.encCert) != 'undefined' ) {
2501
2588
  try {
2502
2589
  altOpt.encCert = fs.readFileSync(options.encCert);
2503
2590
  } catch(err) {
2504
2591
  self.emit('query#complete', err);
2505
2592
  }
2506
-
2593
+
2507
2594
  } else {
2508
2595
  console.warn('[ CONTROLLER ][ HTTP/1.0#query ] options.encCert not found !');
2509
2596
  }
2510
-
2597
+
2511
2598
  altOpt.agent = new browser.Agent(altOpt);
2512
-
2599
+
2513
2600
  var req = browser.request(altOpt, function(res) {
2514
2601
 
2515
2602
  res.setEncoding('utf8');
@@ -2526,24 +2613,24 @@ function SuperController(options) {
2526
2613
  });
2527
2614
 
2528
2615
  res.on('end', function onEnd(err) {
2529
-
2530
-
2616
+
2617
+
2531
2618
  // exceptions filter
2532
2619
  if ( typeof(data) == 'string' && /^Unknown ALPN Protocol/.test(data) ) {
2533
2620
  err = {
2534
2621
  status: 500,
2535
2622
  error: new Error(data)
2536
2623
  };
2537
-
2624
+
2538
2625
  if ( typeof(callback) != 'undefined' ) {
2539
2626
  callback(err)
2540
2627
  } else {
2541
2628
  self.emit('query#complete', err)
2542
2629
  }
2543
-
2630
+
2544
2631
  return
2545
2632
  }
2546
-
2633
+
2547
2634
  //Only when needed.
2548
2635
  if ( typeof(callback) != 'undefined' ) {
2549
2636
  if ( typeof(data) == 'string' && /^(\{|%7B|\[{)|\[\]/.test(data) ) {
@@ -2573,7 +2660,7 @@ function SuperController(options) {
2573
2660
  exception.status = 500;
2574
2661
  self.throwError(exception);
2575
2662
  return;
2576
- }
2663
+ }
2577
2664
 
2578
2665
  } else {
2579
2666
  if ( typeof(data) == 'string' && /^(\{|%7B|\[{)|\[\]/.test(data) ) {
@@ -2600,14 +2687,14 @@ function SuperController(options) {
2600
2687
 
2601
2688
  //starting from from >0.10.15
2602
2689
  req.on('error', function onError(err) {
2603
-
2604
-
2690
+
2691
+
2605
2692
  if (
2606
- typeof(err.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(err.code)
2607
- || typeof(err.cause) != 'undefined' && typeof(err.cause.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(err.cause.code)
2693
+ typeof(err.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(err.code)
2694
+ || typeof(err.cause) != 'undefined' && typeof(err.cause.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(err.cause.code)
2608
2695
  ) {
2609
2696
 
2610
- var port = getContext('gina').ports[options.protocol][options.scheme.replace(/\:/, '')][ options.port ];//err.port || err.cause.port
2697
+ var port = getContext('gina').ports[options.protocol][options.scheme.replace(/\:/, '')][ options.port ];//err.port || err.cause.port
2611
2698
  if ( typeof(port) != 'undefined' ) {
2612
2699
  err.accessPoint = port;
2613
2700
  err.message = '`Controller::query()` could not connect to [ ' + err.accessPoint + ' ] using port '+options.port+'.\n';
@@ -2626,7 +2713,7 @@ function SuperController(options) {
2626
2713
  } else {
2627
2714
  var error = {
2628
2715
  status : 500,
2629
- error : err.stack || err.message
2716
+ error : err.stack || err.message
2630
2717
  };
2631
2718
 
2632
2719
  self.emit('query#complete', error)
@@ -2667,30 +2754,30 @@ function SuperController(options) {
2667
2754
  exception.status = 500;
2668
2755
  self.throwError(exception);
2669
2756
  return;
2670
- }
2757
+ }
2671
2758
  })
2672
2759
  }
2673
-
2760
+
2674
2761
  }
2675
2762
  }
2676
-
2763
+
2677
2764
  var handleHTTP2ClientRequest = function(browser, options, callback) {
2678
-
2679
- //cleanup
2765
+
2766
+ //cleanup
2680
2767
  options[':authority'] = options.hostname;
2681
-
2768
+
2682
2769
  delete options.host;
2683
-
2770
+
2684
2771
  if ( typeof(options[':path']) == 'undefined' ) {
2685
2772
  options[':path'] = options.path;
2686
2773
  delete options.path;
2687
- }
2774
+ }
2688
2775
  if ( typeof(options[':method']) == 'undefined' ) {
2689
2776
  options[':method'] = options.method.toUpperCase();
2690
2777
  delete options.method;
2691
2778
  }
2692
-
2693
- // only if binary !!
2779
+
2780
+ // only if binary !!
2694
2781
  // if ( typeof(options['content-length']) == 'undefined' ) {
2695
2782
  // options['content-length'] = options.headers['content-length'] ;
2696
2783
  // delete options.headers['content-length'];
@@ -2699,11 +2786,11 @@ function SuperController(options) {
2699
2786
  // options['content-type'] = options.headers['content-type'] ;
2700
2787
  // delete options.headers['content-type'];
2701
2788
  // }
2702
-
2789
+
2703
2790
  if ( typeof(options[':scheme']) == 'undefined' ) {
2704
2791
  options[':scheme'] = options.scheme ;
2705
2792
  }
2706
-
2793
+
2707
2794
  if ( typeof(options.ca) != 'undefined' ) {
2708
2795
  try {
2709
2796
  options.ca = fs.readFileSync(options.ca);
@@ -2713,58 +2800,58 @@ function SuperController(options) {
2713
2800
  } else {
2714
2801
  self.emit('query#complete', err);
2715
2802
  }
2716
-
2803
+
2717
2804
  return;
2718
2805
  }
2719
-
2806
+
2720
2807
  } else {
2721
2808
  console.warn('[ CONTROLLER ][ HTTP/2.0#query ] options.ca not found !');
2722
2809
  }
2723
-
2724
-
2810
+
2811
+
2725
2812
  var body = Buffer.from(options.queryData);
2726
- options.headers['content-length'] = body.length;
2813
+ options.headers['content-length'] = body.length;
2727
2814
  delete options.queryData;
2728
-
2729
-
2730
-
2731
- const client = browser.connect(options.hostname, options);
2732
-
2733
-
2815
+
2816
+
2817
+
2818
+ const client = browser.connect(options.hostname, options);
2819
+
2820
+
2734
2821
  const {
2735
2822
  HTTP2_HEADER_PROTOCOL,
2736
- HTTP2_HEADER_SCHEME,
2823
+ HTTP2_HEADER_SCHEME,
2737
2824
  HTTP2_HEADER_AUTHORITY,
2738
2825
  HTTP2_HEADER_PATH,
2739
2826
  HTTP2_HEADER_METHOD,
2740
2827
  HTTP2_HEADER_STATUS
2741
2828
  } = browser.constants;
2742
-
2743
-
2829
+
2830
+
2744
2831
  if ( typeof(local.req.headers['x-requested-with']) != 'undefined' ) {
2745
2832
  options.headers['x-requested-with'] = local.req.headers['x-requested-with']
2746
2833
  }
2747
-
2834
+
2748
2835
  if ( typeof(local.req.headers['access-control-allow-credentials']) != 'undefined' ) {
2749
2836
  options.headers['access-control-allow-credentials'] = local.req.headers['access-control-allow-credentials']
2750
2837
  }
2751
-
2838
+
2752
2839
  if ( typeof(local.req.headers['content-type']) != 'undefined' && local.req.headers['content-type'] != options.headers['content-type'] ) {
2753
2840
  options.headers['content-type'] = local.req.headers['content-type']
2754
2841
  }
2755
-
2756
- var headers = merge({
2842
+
2843
+ var headers = merge({
2757
2844
  [HTTP2_HEADER_METHOD]: options[':method'],
2758
- [HTTP2_HEADER_PATH]: options[':path']
2845
+ [HTTP2_HEADER_PATH]: options[':path']
2759
2846
  }, options.headers);
2760
-
2847
+
2761
2848
  // merging with user options
2762
2849
  for (var o in options) {
2763
2850
  if (!/^\:/.test(o) && !/headers/.test(o) && typeof(headers[o]) == 'undefined' ) {
2764
2851
  headers[o] = options[o]
2765
2852
  }
2766
2853
  }
2767
-
2854
+
2768
2855
  /**
2769
2856
  * sessionOptions
2770
2857
  * endStream <boolean> true if the Http2Stream writable side should be closed initially, such as when sending a GET request that should not expect a payload body.
@@ -2778,55 +2865,55 @@ function SuperController(options) {
2778
2865
  endStream = false;
2779
2866
  sessionOptions.endStream = endStream;
2780
2867
  }
2781
-
2782
-
2868
+
2869
+
2783
2870
  client.on('error', (error) => {
2784
-
2871
+
2785
2872
  console.error( '`'+ options[':path']+ '` : '+ error.stack||error.message);
2786
- if (
2787
- typeof(error.cause) != 'undefined' && typeof(error.cause.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(error.cause.code)
2788
- || /ECONNREFUSED|ECONNRESET/.test(error.code)
2873
+ if (
2874
+ typeof(error.cause) != 'undefined' && typeof(error.cause.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(error.cause.code)
2875
+ || /ECONNREFUSED|ECONNRESET/.test(error.code)
2789
2876
  ) {
2790
-
2877
+
2791
2878
  var port = getContext('gina').ports[options.protocol][options.scheme.replace(/\:/, '')][ options.port ];
2792
2879
  if ( typeof(port) != 'undefined' ) {
2793
2880
  error.accessPoint = port;
2794
2881
  error.message = 'Could not connect to [ ' + error.accessPoint + ' ].\nThe `'+port.split(/\@/)[0]+'` bundle is offline or unreachable.\n';
2795
- }
2882
+ }
2796
2883
  }
2797
2884
  self.throwError(error);
2798
2885
  return;
2799
2886
  });
2800
-
2887
+
2801
2888
  client.on('connect', () => {
2802
-
2889
+
2803
2890
  var req = client.request( headers, sessionOptions );
2804
-
2805
-
2806
- // req.on('response', function onQueryResponse(headers, flags) {
2891
+
2892
+
2893
+ // req.on('response', function onQueryResponse(headers, flags) {
2807
2894
  // for (const name in headers) {
2808
2895
  // console.debug(`${name}: ${headers[name]}`);
2809
2896
  // }
2810
2897
  // });
2811
-
2898
+
2812
2899
  req.setEncoding('utf8');
2813
2900
  var data = '';
2814
- req.on('data', function onQueryDataChunk(chunk) {
2815
- data += chunk;
2901
+ req.on('data', function onQueryDataChunk(chunk) {
2902
+ data += chunk;
2816
2903
  });
2817
-
2904
+
2818
2905
  req.on('error', function onQueryError(error) {
2819
2906
 
2820
- if (
2821
- typeof(error.cause) != 'undefined' && typeof(error.cause.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(error.cause.code)
2822
- || /ECONNREFUSED|ECONNRESET/.test(error.code)
2907
+ if (
2908
+ typeof(error.cause) != 'undefined' && typeof(error.cause.code) != 'undefined' && /ECONNREFUSED|ECONNRESET/.test(error.cause.code)
2909
+ || /ECONNREFUSED|ECONNRESET/.test(error.code)
2823
2910
  ) {
2824
-
2911
+
2825
2912
  var port = getContext('gina').ports[options.protocol][options.scheme.replace(/\:/, '')][ options.port ];
2826
2913
  if ( typeof(port) != 'undefined' ) {
2827
2914
  error.accessPoint = port;
2828
2915
  error.message = 'Could not connect to [ ' + error.accessPoint + ' ].\n' + error.message;
2829
- }
2916
+ }
2830
2917
  }
2831
2918
 
2832
2919
 
@@ -2834,7 +2921,7 @@ function SuperController(options) {
2834
2921
  // you can get here if :
2835
2922
  // - you are trying to query using: `enctype="multipart/form-data"`
2836
2923
  // - server responded with an error
2837
- if ( typeof(callback) != 'undefined' ) {
2924
+ if ( typeof(callback) != 'undefined' ) {
2838
2925
  callback(error);
2839
2926
  } else {
2840
2927
  error = {
@@ -2844,28 +2931,28 @@ function SuperController(options) {
2844
2931
 
2845
2932
  self.emit('query#complete', error)
2846
2933
  }
2847
-
2934
+
2848
2935
  return;
2849
2936
  });
2850
-
2851
- req.on('end', function onEnd() {
2852
-
2937
+
2938
+ req.on('end', function onEnd() {
2939
+
2853
2940
  // exceptions filter
2854
2941
  if ( typeof(data) == 'string' && /^Unknown ALPN Protocol/.test(data) ) {
2855
2942
  var err = {
2856
2943
  status: 500,
2857
2944
  error: new Error(data)
2858
2945
  };
2859
-
2946
+
2860
2947
  if ( typeof(callback) != 'undefined' ) {
2861
2948
  callback(err)
2862
2949
  } else {
2863
2950
  self.emit('query#complete', err)
2864
2951
  }
2865
-
2952
+
2866
2953
  return
2867
2954
  }
2868
-
2955
+
2869
2956
  //Only when needed.
2870
2957
  if ( typeof(callback) != 'undefined' ) {
2871
2958
  if ( typeof(data) == 'string' && /^(\{|%7B|\[{)|\[\]/.test(data) ) {
@@ -2896,24 +2983,24 @@ function SuperController(options) {
2896
2983
  if ( data.status && /^3/.test(data.status) && typeof(data.headers) != 'undefined' ) {
2897
2984
  local.res.writeHead(data.status, data.headers);
2898
2985
  return local.res.end();
2899
- }
2900
-
2986
+ }
2987
+
2901
2988
  if ( data.status && !/^2/.test(data.status) && typeof(local.options.conf.server.coreConfiguration.statusCodes[data.status]) != 'undefined' ) {
2902
2989
  if ( /^5/.test(data.status) ) {
2903
- return callback(data)
2990
+ return callback(data)
2904
2991
  } else {
2905
2992
  self.throwError(data);
2906
2993
  return;
2907
- }
2994
+ }
2908
2995
  } else {
2909
2996
  // required when control is used in an halted state
2910
2997
  // Ref.: resumeRequest()
2911
2998
  if ( self && self.isHaltedRequest() && typeof(local.onHaltedRequestResumed) != 'undefined' ) {
2912
2999
  local.onHaltedRequestResumed(false);
2913
3000
  }
2914
- return callback( false, data )
3001
+ return callback( false, data )
2915
3002
  }
2916
-
3003
+
2917
3004
  } catch (e) {
2918
3005
  var infos = local.options, controllerName = infos.controller.substr(infos.controller.lastIndexOf('/'));
2919
3006
  var msg = 'Controller Query Exception while catching back.\nBundle: '+ infos.bundle +'\nController File: /controllers'+ controllerName +'\nControl: this.'+ infos.control +'(...)\n\r' + e.stack;
@@ -2921,8 +3008,8 @@ function SuperController(options) {
2921
3008
  exception.status = 500;
2922
3009
  self.throwError(exception);
2923
3010
  return;
2924
- }
2925
-
3011
+ }
3012
+
2926
3013
  } else {
2927
3014
  if ( typeof(data) == 'string' && /^(\{|%7B|\[{)|\[\]/.test(data) ) {
2928
3015
  try {
@@ -2935,13 +3022,13 @@ function SuperController(options) {
2935
3022
  self.emit('query#complete', data)
2936
3023
  }
2937
3024
  }
2938
-
3025
+
2939
3026
  // intercepting fallback redirect
2940
3027
  if ( data.status && /^3/.test(data.status) && typeof(data.headers) != 'undefined' ) {
2941
3028
  self.removeAllListeners(['query#complete']);
2942
3029
  local.res.writeHead(data.status, data.headers);
2943
3030
  return local.res.end();
2944
- }
3031
+ }
2945
3032
 
2946
3033
  if ( data.status && !/^2/.test(data.status) && typeof(local.options.conf.server.coreConfiguration.statusCodes[data.status]) != 'undefined' ) {
2947
3034
  self.emit('query#complete', data)
@@ -2953,22 +3040,22 @@ function SuperController(options) {
2953
3040
  }
2954
3041
  self.emit('query#complete', false, data)
2955
3042
  }
2956
- }
2957
-
3043
+ }
3044
+
2958
3045
  client.close();
2959
3046
  });
2960
-
3047
+
2961
3048
  if (!endStream) {
2962
3049
  req.end(body);
2963
3050
  }
2964
3051
  });
2965
-
2966
-
3052
+
3053
+
2967
3054
  return {
2968
3055
  onComplete : function(cb) {
2969
-
3056
+
2970
3057
  self.once('query#complete', function(err, data){
2971
-
3058
+
2972
3059
  if ( typeof(data) == 'string' && /^(\{|%7B|\[{)|\[\]/.test(data) ) {
2973
3060
  try {
2974
3061
  data = JSON.parse(data)
@@ -2979,7 +3066,7 @@ function SuperController(options) {
2979
3066
  }
2980
3067
  }
2981
3068
  }
2982
-
3069
+
2983
3070
  try {
2984
3071
  if ( data.status && !/^2/.test(data.status) && typeof(local.options.conf.server.coreConfiguration.statusCodes[data.status]) != 'undefined') {
2985
3072
  cb(data)
@@ -2989,7 +3076,7 @@ function SuperController(options) {
2989
3076
  if ( self.isHaltedRequest() && typeof(local.onHaltedRequestResumed) != 'undefined' ) {
2990
3077
  local.onHaltedRequestResumed(err);
2991
3078
  }
2992
-
3079
+
2993
3080
  cb(err, data)
2994
3081
  }
2995
3082
  } catch (e) {
@@ -2999,7 +3086,7 @@ function SuperController(options) {
2999
3086
  exception.status = 500;
3000
3087
  self.throwError(exception);
3001
3088
  return;
3002
- }
3089
+ }
3003
3090
  })
3004
3091
  }
3005
3092
  }
@@ -3066,8 +3153,8 @@ function SuperController(options) {
3066
3153
  }
3067
3154
 
3068
3155
  req.getParam = function(name) {
3069
-
3070
- var param = null;
3156
+
3157
+ var param = null;
3071
3158
  switch( req.method.toLowerCase() ) {
3072
3159
  case 'get':
3073
3160
  param = req.get[name];
@@ -3089,24 +3176,24 @@ function SuperController(options) {
3089
3176
  return param
3090
3177
  }
3091
3178
  }
3092
-
3179
+
3093
3180
  /**
3094
- * Forward request
3181
+ * Forward request
3095
3182
  * Allowing x-bundle forward
3096
3183
  * Attention: this is a work in progres, do not use it yet
3097
- *
3098
- * @param {object} req
3099
- * @param {object} res
3100
- * @param {callback} next
3101
- * @returns
3184
+ *
3185
+ * @param {object} req
3186
+ * @param {object} res
3187
+ * @param {callback} next
3188
+ * @returns
3102
3189
  */
3103
3190
  this.forward = function(req, res, next) {
3104
3191
  var route = req.routing;
3105
3192
  if ( typeof(route.param.url) == 'undefined' || /^(null|\s*)$/.test(route.param.url) ) {
3106
3193
  self.throwError( new Error('`route.param.url` must be defiend in your route: `'+ route.rule +'`') );
3107
3194
  return;
3108
- }
3109
-
3195
+ }
3196
+
3110
3197
  var param = {};
3111
3198
  for (let p in route.param) {
3112
3199
  if ( /^(url|urlIndex|control|file|title|bundle|project|hostname|port|path|method)$/.test(p) ) {
@@ -3138,14 +3225,14 @@ function SuperController(options) {
3138
3225
  port = route.param.port;
3139
3226
  path = route.param.port;
3140
3227
  }
3141
-
3228
+
3142
3229
  var method = null;
3143
3230
  if ( typeof(route.param.method) != 'undefined' ) {
3144
3231
  method = route.param.method.toLowerCase();
3145
3232
  } else {
3146
3233
  method = req.method.toLowerCase();
3147
3234
  }
3148
-
3235
+
3149
3236
  var opt = {
3150
3237
  ca: ca,
3151
3238
  hostname: hostname,
@@ -3156,7 +3243,7 @@ function SuperController(options) {
3156
3243
  if (self.isCacheless() || self.isLocalScope() ) {
3157
3244
  opt.rejectUnauthorized = false;
3158
3245
  }
3159
-
3246
+
3160
3247
  var obj = req[ req.method.toLowerCase() ];
3161
3248
  // if ( req.files != 'undefined' ) {
3162
3249
  // obj.files = req.files;
@@ -3166,17 +3253,17 @@ function SuperController(options) {
3166
3253
  self.throwError(err);
3167
3254
  return;
3168
3255
  }
3169
-
3256
+
3170
3257
  // TODO - filter : redirect & location
3171
-
3172
- // if ( self.isXMLRequest() || !hasViews() || !local.options.isUsingTemplate && !hasViews() || hasViews() && !local.options.isUsingTemplate ) {
3258
+
3259
+ // if ( self.isXMLRequest() || !hasViews() || !local.options.isUsingTemplate && !hasViews() || hasViews() && !local.options.isUsingTemplate ) {
3173
3260
  self.renderJSON(result)
3174
3261
  // } else {
3175
3262
  // self.render(result)
3176
- // }
3263
+ // }
3177
3264
  });
3178
3265
  }
3179
-
3266
+
3180
3267
 
3181
3268
  /**
3182
3269
  * Get config
@@ -3193,6 +3280,8 @@ function SuperController(options) {
3193
3280
  //config = Object.freeze(local.options.conf.content[name]);
3194
3281
  //Object.seal(local.options.conf.content[name]);
3195
3282
  //Object.freeze(local.options.conf.content[name]);
3283
+ // if ( self.isCacheless() ) {
3284
+ // }
3196
3285
  return JSON.clone(local.options.conf.content[name]);
3197
3286
  } catch (err) {
3198
3287
  return undefined;
@@ -3206,6 +3295,7 @@ function SuperController(options) {
3206
3295
 
3207
3296
  /**
3208
3297
  * Get locales
3298
+ * Will take only supported lang
3209
3299
  *
3210
3300
  * @param {string} [shortCountryCode] - e.g. EN
3211
3301
  *
@@ -3231,29 +3321,27 @@ function SuperController(options) {
3231
3321
  /**
3232
3322
  * Get countries list
3233
3323
  *
3234
- * @param {string} [code] - e.g.: short, long, fifa, m49
3324
+ * @param {string} [code] - e.g.: officialStateName, isoShort, isoLong, continent, capital, currency.name
3235
3325
  *
3236
3326
  * @returns {object} countries - countries code & value list
3237
3327
  * */
3238
3328
  var getCountries = function (code) {
3239
- var list = {}, cde = 'short', name = null;
3329
+ var list = [], cde = 'countryName';
3240
3330
 
3241
3331
  if ( typeof(code) != 'undefined' && typeof(userLocales[0][code]) == 'string' ) {
3242
3332
  cde = code
3243
- } else if ( typeof(code) != 'undefined' ) (
3333
+ } else if ( typeof(code) != 'undefined' ) {
3244
3334
  console.warn('`'+ code +'` not supported : sticking with `short` code')
3245
- )
3246
-
3247
-
3248
- for ( var i = 0, len = userLocales.length; i< len; ++i ) {
3249
-
3250
- if (userLocales[i][cde]) {
3335
+ }
3251
3336
 
3252
- name = userLocales[i].officialName.short || userLocales[i].full;
3253
3337
 
3254
- if ( name )
3255
- list[ userLocales[i][cde] ] = name;
3256
- }
3338
+ for ( let i = 0, len = userLocales.length; i< len; ++i ) {
3339
+ list[ i ] = {
3340
+ isoShort: userLocales[i].isoShort,
3341
+ isoLong: userLocales[i].isoLong,
3342
+ countryName: userLocales[i].countryName,
3343
+ officialStateName: userLocales[i].officialStateName
3344
+ };
3257
3345
  }
3258
3346
 
3259
3347
  return list
@@ -3261,6 +3349,7 @@ function SuperController(options) {
3261
3349
 
3262
3350
  return {
3263
3351
  'getCountries': getCountries
3352
+ // TODO - getCurrencies()
3264
3353
  }
3265
3354
  }
3266
3355
 
@@ -3297,8 +3386,8 @@ function SuperController(options) {
3297
3386
  } else {
3298
3387
  rules = JSON.clone(local.options.conf.content.forms).rules[form.id] || null;
3299
3388
  }
3300
-
3301
- if (!rules) {
3389
+
3390
+ if (!rules) {
3302
3391
  rules = {};
3303
3392
  console.warn('[CONTROLLER]['+ local.options.conf.bundle +'][Backend validation] did not find matching rules for form.id `'+ form.id +'` for `'+ bundle+' bundle`. Do not Panic if you did not defined any.')
3304
3393
  }
@@ -3307,40 +3396,40 @@ function SuperController(options) {
3307
3396
  return;
3308
3397
  }
3309
3398
  }
3310
-
3399
+
3311
3400
  return rules;
3312
3401
  }
3313
-
3402
+
3314
3403
  this.push = function(payload) {
3315
-
3404
+
3316
3405
  var req = local.req, res = local.res;
3317
3406
  var method = req.method.toLowerCase();
3318
3407
  // if no session defined, will push to all active clients
3319
3408
  var sessionId = ( typeof(req[method].sessionID) != 'undefined' ) ? req[method].sessionID : null;
3320
-
3409
+
3321
3410
  // resume current session
3322
-
3323
- if (!payload) {
3324
- payload = null;
3411
+
3412
+ if (!payload) {
3413
+ payload = null;
3325
3414
  if ( typeof(req[method]) != 'undefined' && typeof(req[method].payload) != 'undefined' ) {
3326
3415
  if ( typeof(payload) == 'string' ) {
3327
3416
  payload = decodeURIComponent(req[method].payload)
3328
3417
  } else {
3329
3418
  payload = JSON.stringify(req[method].payload)
3330
- }
3419
+ }
3331
3420
  }
3332
3421
  } else if ( typeof(payload) == 'object' ) {
3333
3422
  payload = JSON.stringify(payload)
3334
- }
3335
-
3423
+ }
3424
+
3336
3425
  try {
3337
3426
  var clients = null;
3338
3427
  if (sessionId) {
3339
3428
  clients = self.serverInstance.eio.getClientsBySessionId(sessionId);
3340
3429
  if (clients)
3341
3430
  clients.send(payload);
3342
- }
3343
-
3431
+ }
3432
+
3344
3433
  // send to all clients if no specific sessionId defined
3345
3434
  if (!sessionId) {
3346
3435
  clients = self.serverInstance.eio.clients;
@@ -3348,14 +3437,14 @@ function SuperController(options) {
3348
3437
  clients[id].send(payload)
3349
3438
  }
3350
3439
  }
3351
-
3440
+
3352
3441
  res.end();
3353
3442
  } catch(err) {
3354
3443
  self.throwError(err);
3355
3444
  return;
3356
- }
3445
+ }
3357
3446
  }
3358
-
3447
+
3359
3448
  var getSession = function() {
3360
3449
  var session = null;
3361
3450
  if ( typeof(local.req.session) != 'undefined') {
@@ -3365,10 +3454,10 @@ function SuperController(options) {
3365
3454
  if (!session && typeof(local.req.session) != 'undefined' && typeof(local.req.session.user) != 'undefined') {
3366
3455
  session = local.req.session.user;
3367
3456
  }
3368
-
3457
+
3369
3458
  return session;
3370
3459
  }
3371
-
3460
+
3372
3461
  this.isHaltedRequest = function(session) {
3373
3462
  // trying to retrieve session since it is optional
3374
3463
  if ( typeof(session) == 'undefined' ) {
@@ -3381,24 +3470,24 @@ function SuperController(options) {
3381
3470
  // session = local.req.session.user;
3382
3471
  // }
3383
3472
  if (
3384
- !session
3385
- ||
3473
+ !session
3474
+ ||
3386
3475
  typeof(session) != 'undefined'
3387
3476
  && typeof(session.haltedRequest) == 'undefined'
3388
3477
  ) {
3389
3478
  return false;
3390
3479
  }
3391
3480
  }
3392
-
3481
+
3393
3482
  return (typeof(session.haltedRequest) != 'undefined' ) ? true : false;
3394
3483
  }
3395
-
3396
-
3484
+
3485
+
3397
3486
  local.haltedRequestUrlResumed = false;
3398
-
3487
+
3399
3488
  this.pauseRequest = function(data, requestStorage) {
3400
-
3401
-
3489
+
3490
+
3402
3491
  // saving halted request
3403
3492
  var req = local.req
3404
3493
  , res = local.res
@@ -3410,22 +3499,22 @@ function SuperController(options) {
3410
3499
  data : JSON.clone(data)
3411
3500
  }
3412
3501
  ;
3413
-
3502
+
3414
3503
  if (
3415
3504
  typeof(requestStorage) == 'undefined'
3416
3505
  && typeof(req.session) != 'undefined'
3417
3506
  ) {
3418
3507
  requestStorage = req.session;
3419
3508
  }
3420
-
3509
+
3421
3510
  if (
3422
- typeof(requestStorage) == 'undefined'
3511
+ typeof(requestStorage) == 'undefined'
3423
3512
  ) {
3424
3513
  var error = new ApiError('`requestStorage` is required', 424);
3425
3514
  self.throwError(error);
3426
3515
  return;
3427
3516
  }
3428
-
3517
+
3429
3518
  var requestParams = {}, i = 0;
3430
3519
  for (var p in req.params) {
3431
3520
  if (i > 0) {
@@ -3436,13 +3525,13 @@ function SuperController(options) {
3436
3525
  if (requestParams.count() > 0) {
3437
3526
  haltedRequest.params = requestParams;
3438
3527
  }
3439
-
3528
+
3440
3529
  requestStorage.haltedRequest = haltedRequest;
3441
-
3530
+
3442
3531
  return requestStorage;
3443
3532
  }
3444
-
3445
-
3533
+
3534
+
3446
3535
  /**
3447
3536
  * resumeRequest
3448
3537
  * Used to resume an halted request
@@ -3450,35 +3539,35 @@ function SuperController(options) {
3450
3539
  * - a middleware attached `haltedRequest` to userSession
3451
3540
  * OR
3452
3541
  * - a persistant object where `haltedRequest` is attached
3453
- *
3454
- * @param {object} req
3455
- * @param {object} res
3542
+ *
3543
+ * @param {object} req
3544
+ * @param {object} res
3456
3545
  * @param {callback|null} next
3457
3546
  * @param {object} [requestStorage] - Will try to use sessionStorage if not passed
3458
3547
  */
3459
3548
  this.resumeRequest = function(requestStorage) {
3460
-
3549
+
3461
3550
  if (local.haltedRequestUrlResumed)
3462
3551
  return;
3463
-
3552
+
3464
3553
  var haltedRequest = null
3465
3554
  , req = local.req
3466
3555
  , res = local.res
3467
3556
  , next = local.next
3468
3557
  ;
3469
-
3558
+
3470
3559
  if (
3471
3560
  typeof(requestStorage) == 'undefined'
3472
3561
  && typeof(req.session) != 'undefined'
3473
3562
  ) {
3474
3563
  requestStorage = req.session;
3475
3564
  }
3476
-
3565
+
3477
3566
  if (
3478
- typeof(requestStorage) == 'undefined'
3567
+ typeof(requestStorage) == 'undefined'
3479
3568
  ||
3480
- typeof(requestStorage) != 'undefined'
3481
- && typeof(requestStorage.haltedRequest) == 'undefined'
3569
+ typeof(requestStorage) != 'undefined'
3570
+ && typeof(requestStorage.haltedRequest) == 'undefined'
3482
3571
  ) {
3483
3572
  var error = new ApiError('`requestStorage.haltedRequest` is required', 424);
3484
3573
  self.throwError(error);
@@ -3493,11 +3582,11 @@ function SuperController(options) {
3493
3582
  if (req.method.toLowerCase() == method) {
3494
3583
  data = merge(data, req[method])
3495
3584
  }
3496
-
3497
- delete req[method];
3585
+
3586
+ delete req[method];
3498
3587
  }
3499
-
3500
-
3588
+
3589
+
3501
3590
  var dataAsParams = {};
3502
3591
  if (data.count() > 0) {
3503
3592
  dataAsParams = JSON.clone(haltedRequest.data);
@@ -3509,25 +3598,45 @@ function SuperController(options) {
3509
3598
  requiredController = self.requireController(haltedRequest.routing.namespace, self._options );
3510
3599
  } catch (err) {
3511
3600
  self.throwError(err);
3512
- }
3601
+ }
3513
3602
  }
3514
3603
  req.routing = haltedRequest.routing;
3515
3604
  req.method = haltedRequest.method;
3516
3605
  req[haltedRequest.method] = data;
3517
-
3606
+
3518
3607
  local.haltedRequestUrlResumed = true;
3519
- if ( /GET/i.test(req.method) ) {
3608
+ if ( /GET/i.test(req.method) ) {
3520
3609
  if ( typeof(requestStorage.haltedRequest) != 'undefined' ) {
3521
3610
  delete requestStorage.haltedRequest;
3522
3611
  }
3523
3612
  delete requestStorage.haltedRequest;
3524
3613
  delete requestStorage.inheritedData;
3525
3614
  requestStorage.haltedRequestUrlResumed = url;
3526
-
3615
+
3616
+ if (
3617
+ typeof(req.routing.param.isPopinContext) != 'undefined'
3618
+ && /^true$/i.test(req.routing.param.isPopinContext)
3619
+ && self.isXMLRequest()
3620
+ ) {
3621
+ return self.renderJSON({
3622
+ isXhrRedirect: true,
3623
+ popin: {
3624
+ url: url
3625
+ }
3626
+ })
3627
+ }
3628
+ else if (self.isXMLRequest() ) {
3629
+ return self.renderJSON({
3630
+ isXhrRedirect: true,
3631
+ location: url
3632
+ })
3633
+ }
3634
+
3527
3635
  requiredController.redirect(url, true);
3636
+
3528
3637
  } else {
3529
3638
  local.onHaltedRequestResumed = function(err) {
3530
- if (!err) {
3639
+ if (!err) {
3531
3640
  delete requestStorage.haltedRequest;
3532
3641
  delete requestStorage.inheritedData;
3533
3642
  }
@@ -3535,7 +3644,7 @@ function SuperController(options) {
3535
3644
  if ( typeof(next) == 'function' ) {
3536
3645
  console.warn('About to override `next` param');
3537
3646
  }
3538
-
3647
+
3539
3648
  try {
3540
3649
  requiredController[req.routing.param.control](req, res, next);
3541
3650
  // consuming it
@@ -3544,12 +3653,12 @@ function SuperController(options) {
3544
3653
  console.error('[ BUNDLE ][ '+ local.options.conf.bundle +' ][ Controller ] Could not resume haltedRequest\n' + err.stack );
3545
3654
  self.throwError(err);
3546
3655
  }
3547
-
3548
-
3549
- }
3656
+
3657
+
3658
+ }
3550
3659
  }
3551
-
3552
-
3660
+
3661
+
3553
3662
  this.renderCustomError = function (req, res, next) {
3554
3663
 
3555
3664
  // preventing multiple call of self.renderWithoutLayout() when controller is rendering from another required controller
@@ -3559,16 +3668,19 @@ function SuperController(options) {
3559
3668
  local.options.isRenderingCustomError = true;
3560
3669
 
3561
3670
  //local.options.isWithoutLayout = true;
3562
-
3671
+
3563
3672
  var data = null;
3564
3673
  if ( typeof(req.routing.param.error) != 'undefined' ) {
3565
3674
  data = JSON.clone(req.routing.param.error) || {};
3566
3675
  delete req.routing.param.error
3567
3676
  }
3568
-
3677
+
3569
3678
  var session = getSession();
3570
3679
  if (session) {
3571
- data.session = JSON.clone(session)
3680
+ if (!data) {
3681
+ data = {}
3682
+ }
3683
+ data.session = ( typeof(session.user) != 'undefined' ) ? JSON.clone(session.user) : JSON.clone(session);
3572
3684
  }
3573
3685
  var displayToolbar = req.routing.param.displayToolbar || false;
3574
3686
  if (req.routing.param.displayToolbar) {
@@ -3603,13 +3715,27 @@ function SuperController(options) {
3603
3715
  //assets: {}
3604
3716
  };
3605
3717
  errOptions = merge(localOptions, local.options);
3606
-
3607
-
3718
+
3719
+
3608
3720
  }
3609
3721
  delete local.options.namespace;
3610
3722
  self.render(data, displayToolbar, errOptions);
3611
3723
  }
3612
-
3724
+
3725
+ var getResponseProtocol = function (response) {
3726
+ // var options = local.options;
3727
+ // var protocolVersion = ~~options.conf.server.protocol.match(/\/(.*)$/)[1].replace(/\.\d+/, '');
3728
+
3729
+ var protocol = 'http/'+ local.req.httpVersion; // inheriting request protocol version by default
3730
+ var bundleConf = options.conf;
3731
+ // switching protocol to h2 when possible
3732
+ if ( /http\/2/.test(bundleConf.server.protocol) && response.stream ) {
3733
+ protocol = bundleConf.server.protocol;
3734
+ }
3735
+
3736
+ return protocol;
3737
+ }
3738
+
3613
3739
 
3614
3740
  /**
3615
3741
  * Throw error
@@ -3621,9 +3747,14 @@ function SuperController(options) {
3621
3747
  * @returns {void}
3622
3748
  * */
3623
3749
  this.throwError = function(res, code, msg) {
3750
+
3751
+ var protocol = getResponseProtocol(res);
3752
+ var stream = ( /http\/2/.test(protocol) && res.stream ) ? res.stream : null;
3753
+ var header = ( /http\/2/.test(protocol) && res.stream ) ? {} : null;
3754
+
3624
3755
  self.isProcessingError = true;
3625
3756
  var errorObject = null; // to be returned
3626
-
3757
+
3627
3758
  // preventing multiple call of self.throwError() when controller is rendering from another required controller
3628
3759
  if (local.options.renderingStack.length > 1) {
3629
3760
  return false
@@ -3634,21 +3765,22 @@ function SuperController(options) {
3634
3765
  // err.fallback must be a valide route object or a url string
3635
3766
  var fallback = null;
3636
3767
  var standardErrorMessage = null;
3637
- if (
3638
- arguments[0] instanceof Error
3768
+ if (
3769
+ arguments[0] instanceof Error
3639
3770
  || arguments.length == 1 && typeof(res) == 'object'
3640
3771
  || arguments[arguments.length-1] instanceof Error
3641
- || typeof(arguments[arguments.length-1]) == 'string' && !(arguments[0] instanceof Error)
3772
+ || typeof(arguments[arguments.length-1]) == 'string' && !(arguments[0] instanceof Error)
3642
3773
  ) {
3643
-
3644
- code = ( res && typeof(res.status) != 'undefined' ) ? res.status : 500;
3645
-
3774
+
3775
+ msg = ( !/^\d+$/.test(code) && typeof(msg) == 'undefined' ) ? code : msg;
3776
+ code = ( res && typeof(res.status) != 'undefined' ) ? res.status : 500;
3777
+
3646
3778
  if ( typeof(statusCodes[code]) != 'undefined' ) {
3647
3779
  standardErrorMessage = statusCodes[code];
3648
3780
  } else {
3649
3781
  console.warn('[ ApiValidator ] statusCode `'+ code +'` not matching any definition in `'+_( getPath('gina').core + '/status.codes')+'`\nPlease contact the Gina dev team to add one if required');
3650
3782
  }
3651
-
3783
+
3652
3784
  errorObject = {
3653
3785
  status : code,
3654
3786
  error : res.error || res.message || standardErrorMessage
@@ -3663,17 +3795,18 @@ function SuperController(options) {
3663
3795
  } else if (res.message) {
3664
3796
  console.warn('[ Controller ] Ignoring message because of the format.\n'+res.message)
3665
3797
  }
3666
-
3798
+
3667
3799
  } else if ( typeof(arguments[arguments.length-1]) == 'string' ) {
3668
3800
  // formated error
3669
- errorObject.message = arguments[arguments.length-1]
3801
+ errorObject.message = arguments[arguments.length-1] || msg
3802
+ // errorObject = merge(arguments[arguments.length-1], errorObject)
3670
3803
  } else if (
3671
- arguments[arguments.length-1] instanceof Error
3672
- || typeof(res) == 'object' && typeof(res.stack) != 'undefined'
3804
+ arguments[arguments.length-1] instanceof Error
3805
+ || typeof(res) == 'object' && typeof(res.stack) != 'undefined'
3673
3806
  ) {
3674
3807
  errorObject = merge(arguments[arguments.length-1], errorObject)
3675
3808
  }
3676
-
3809
+
3677
3810
  if ( typeof(res.fallback) != 'undefined' ) {
3678
3811
  fallback = res.fallback
3679
3812
  }
@@ -3685,27 +3818,33 @@ function SuperController(options) {
3685
3818
  code = res || 500;
3686
3819
  res = local.res;
3687
3820
  }
3688
-
3689
- var responseHeaders = res.getHeaders() || local.res.getHeaders();
3821
+
3822
+ var responseHeaders = null;
3823
+ if ( typeof(res.getHeaders) == 'undefined' && typeof(res.stream) != 'undefined' ) {
3824
+ responseHeaders = res.stream.sentHeader;
3825
+ } else {
3826
+ responseHeaders = res.getHeaders() || local.res.getHeaders();
3827
+ }
3828
+ // var responseHeaders = res.getHeaders() || local.res.getHeaders();
3690
3829
  var req = local.req;
3691
3830
  var next = local.next;
3692
- if (!res.headersSent) {
3831
+ if (!headersSent()) {
3693
3832
  // DELETE request methods don't normaly use a view,
3694
3833
  // but if we are calling it from a view, we should render the error back to the view
3695
- if ( self.isXMLRequest() || !hasViews() && !/delete/i.test(req.method) || !local.options.isUsingTemplate && !hasViews() || hasViews() && !local.options.isUsingTemplate ) {
3834
+ if ( self.isXMLRequest() || !hasViews() && !/delete/i.test(req.method) || !local.options.isUsingTemplate && !hasViews() || hasViews() && !local.options.isUsingTemplate ) {
3696
3835
  // fallback interception
3697
- if ( fallback ) {
3836
+ if ( fallback ) {
3698
3837
  if ( typeof(fallback) == 'string' ){ // string url: user provided
3699
3838
  return self.redirect( fallback, true )
3700
3839
  } else {
3701
3840
  // else, using url from route object
3702
3841
  // Reminder
3703
3842
  // Here, we use route.toUrl() intead of
3704
- // route.url to support x-bundle com
3843
+ // route.url to support x-bundle com
3705
3844
  return self.redirect( fallback.toUrl() );
3706
3845
  }
3707
3846
  }
3708
-
3847
+
3709
3848
  // allowing this.throwError(err)
3710
3849
  if ( typeof(code) == 'object' && !msg && typeof(code.status) != 'undefined' && typeof(code.error) != 'undefined' ) {
3711
3850
  msg = code.error || code.message;
@@ -3717,7 +3856,7 @@ function SuperController(options) {
3717
3856
  console.warn('[ ApiValidator ] statusCode `'+ code +'` not matching any definition in `'+_( getPath('gina').core + '/status.codes')+'`\nPlease contact the Gina dev team to add one if required');
3718
3857
  }
3719
3858
 
3720
- // if ( !local.res.getHeaders()['content-type'] /**!req.headers['content-type'] */  ) {
3859
+ // if ( !local.res.getHeaders()['content-type'] /**!req.headers['content-type'] */ ) {
3721
3860
  // // Internet Explorer override
3722
3861
  // if ( typeof(req.headers['user-agent']) != 'undefined' && /msie/i.test(req.headers['user-agent']) ) {
3723
3862
  // res.writeHead(code, "content-type", "text/plain")
@@ -3725,7 +3864,7 @@ function SuperController(options) {
3725
3864
  // res.writeHead(code, { 'content-type': bundleConf.server.coreConfiguration.mime['json']} );
3726
3865
  // }
3727
3866
  // }
3728
-
3867
+
3729
3868
  // TODO - test with internet explorer then remove this if working
3730
3869
  if ( typeof(req.headers['user-agent']) != 'undefined' ) {
3731
3870
  if ( /msie/i.test(req.headers['user-agent']) ) {
@@ -3743,8 +3882,8 @@ function SuperController(options) {
3743
3882
  res.writeHead(code, "content-type", bundleConf.server.coreConfiguration.mime['json']+ '; charset='+ bundleConf.encoding);
3744
3883
  }
3745
3884
 
3746
-
3747
-
3885
+
3886
+
3748
3887
  if (!errorObject) {
3749
3888
  errorObject = {
3750
3889
  status: code,
@@ -3754,7 +3893,7 @@ function SuperController(options) {
3754
3893
  stack: msg.stack
3755
3894
  }
3756
3895
  }
3757
-
3896
+
3758
3897
  var errOutput = null, output = errorObject.toString();
3759
3898
  if ( output == '[object Object]' ) {
3760
3899
  errOutput = JSON.stringify(errorObject);
@@ -3762,21 +3901,23 @@ function SuperController(options) {
3762
3901
  errOutput = JSON.stringify(
3763
3902
  {
3764
3903
  status : errorObject.status,
3765
- error : output
3904
+ error : output,
3905
+ stack : errorObject.stack || null
3766
3906
  }
3767
3907
  );
3768
3908
  }
3769
-
3770
- console.error('[ BUNDLE ][ '+ bundleConf.bundle +' ][ Controller ] '+ req.method +' ['+res.statusCode +'] '+ req.url +'\n'+ errOutput);
3909
+
3910
+ // console.error('[ BUNDLE ][ '+ bundleConf.bundle +' ][ Controller ] '+ req.method +' ['+res.statusCode +'] '+ req.url +'\n'+ errorObject);
3911
+ console.error('[ BUNDLE ][ '+ bundleConf.bundle +' ][ Controller ] '+ req.method +' ['+res.statusCode +'] '+ req.url +'\n'+ errOutput);
3771
3912
  return res.end(errOutput);
3772
3913
  } else {
3773
-
3774
-
3775
- console.error(req.method +' ['+ errorObject.status +'] '+ req.url);
3776
-
3777
-
3914
+
3915
+
3916
+ console.error(req.method +' ['+ errorObject.status +'] '+ req.url + '\n'+ (errorObject.stack||errorObject.message));
3917
+
3918
+
3778
3919
  // intercept none HTML mime types
3779
- var url = unescape(local.req.url) /// avoid %20
3920
+ var url = decodeURI(local.req.url) /// avoid %20
3780
3921
  , ext = null
3781
3922
  , isHtmlContent = false
3782
3923
  , hasCustomErrorFile = false
@@ -3788,9 +3929,12 @@ function SuperController(options) {
3788
3929
  }
3789
3930
  if ( !ext || /^(html|htm)$/i.test(ext) ) {
3790
3931
  isHtmlContent = true;
3932
+ if (!ext) {
3933
+ ext = 'html'
3934
+ }
3791
3935
  }
3792
-
3793
- if (
3936
+
3937
+ if (
3794
3938
  isHtmlContent
3795
3939
  && typeof(bundleConf.content.templates._common.errorFiles) != 'undefined'
3796
3940
  && typeof(bundleConf.content.templates._common.errorFiles[code]) != 'undefined'
@@ -3810,11 +3954,11 @@ function SuperController(options) {
3810
3954
  //message : errorObject.message || msg || null,
3811
3955
  pathname : url
3812
3956
  };
3813
-
3957
+
3814
3958
  if ( errorObject ) {
3815
3959
  eData = merge(errorObject, eData);
3816
3960
  }
3817
-
3961
+
3818
3962
  if ( typeof(msg) == 'object' ) {
3819
3963
  if ( typeof(msg.stack) != 'undefined' ) {
3820
3964
  eData.stack = msg.stack
@@ -3823,8 +3967,8 @@ function SuperController(options) {
3823
3967
  eData.message = msg.message
3824
3968
  }
3825
3969
  }
3826
- if (
3827
- code
3970
+ if (
3971
+ code
3828
3972
  // See: framework/${version}/core/status.code
3829
3973
  && typeof(bundleConf.server.coreConfiguration.statusCodes[code]) != 'undefined'
3830
3974
  ) {
@@ -3834,33 +3978,33 @@ function SuperController(options) {
3834
3978
  // if ( typeof(local.req.routing) != 'undefined' ) {
3835
3979
  // eData.routing = local.req.routing;
3836
3980
  // }
3837
-
3981
+
3838
3982
  if (typeof(bundleConf.content.templates._common.errorFiles[code]) != 'undefined') {
3839
3983
  eFilename = bundleConf.content.templates._common.errorFiles[code];
3840
3984
  } else {
3841
3985
  eFilename = bundleConf.content.templates._common.errorFiles[eCode];
3842
3986
  }
3843
-
3987
+
3844
3988
  if (!local.options.isRenderingCustomError) {
3845
3989
  var eRule = 'custom-error-page@'+ bundle;
3846
3990
  var routeObj = bundleConf.content.routing[eRule];
3847
3991
  routeObj.rule = eRule;
3848
- //routeObj.url = unescape(local.req.url);/// avoid %20
3992
+ //routeObj.url = decodeURI(local.req.url);/// avoid %20
3849
3993
  routeObj.param.title = ( typeof(eData.title) != 'undefined' ) ? eData.title : 'Error ' + eData.status;
3850
3994
  routeObj.param.file = eFilename;
3851
3995
  routeObj.param.error = eData;
3852
3996
  routeObj.param.displayToolbar = self.isCacheless();
3853
3997
  routeObj.param.isLocalOptionResetNeeded = true;
3854
-
3855
-
3998
+
3999
+
3856
4000
  local.req.routing = routeObj;
3857
4001
  local.req.params.errorObject = errorObject;
3858
4002
  self.renderCustomError(local.req, res, local.next);
3859
4003
  return;
3860
4004
  }
3861
-
4005
+
3862
4006
  }
3863
-
4007
+
3864
4008
  // if (!errorObject) {
3865
4009
  // errorObject = {
3866
4010
  // status: code,
@@ -3871,7 +4015,7 @@ function SuperController(options) {
3871
4015
  // }
3872
4016
  // }
3873
4017
  var msgString = '<h1 class="status">Error '+ code +'.</h1>';
3874
-
4018
+
3875
4019
  console.error('[ BUNDLE ][ '+ local.options.conf.bundle +' ][ Controller ] `this.'+ req.routing.param.control +'(...)` ['+res.statusCode +'] '+ req.url);
3876
4020
  if ( typeof(msg) == 'object' ) {
3877
4021
 
@@ -3913,7 +4057,7 @@ function SuperController(options) {
3913
4057
  if (typeof(errorObject) != 'undefined' && errorObject && typeof(errorObject.stack) != 'undefined' ) {
3914
4058
  stack = errorObject.stack
3915
4059
  }
3916
-
4060
+
3917
4061
  if (title) {
3918
4062
  msgString += '<pre class="'+ eCode +' title">'+ title +'</pre>';
3919
4063
  }
@@ -3922,7 +4066,7 @@ function SuperController(options) {
3922
4066
  }
3923
4067
  if (stack) {
3924
4068
  msgString += '<pre class="'+ eCode +' stack">'+ stack +'</pre>';
3925
- }
4069
+ }
3926
4070
  }
3927
4071
  res.writeHead(code, { 'content-type': bundleConf.server.coreConfiguration.mime[ext]+'; charset='+ bundleConf.encoding } );
3928
4072
  // if ( isHtmlContent && hasCustomErrorFile ) {
@@ -3931,15 +4075,19 @@ function SuperController(options) {
3931
4075
  //if ( isHtmlContent && !hasCustomErrorFile ) {
3932
4076
  res.end(msgString);
3933
4077
  //}
3934
-
4078
+
3935
4079
  return;
3936
4080
  }
3937
4081
  } else {
3938
4082
  if (typeof(next) != 'undefined')
3939
4083
  return next();
3940
4084
  }
3941
- res.end();
3942
- return;
4085
+
4086
+ if ( /http\/2/.test(protocol) ) {
4087
+ return stream.end();
4088
+ }
4089
+
4090
+ return res.end();
3943
4091
  }
3944
4092
 
3945
4093
  // converting references to objects