vulcan 0.6.1 → 0.7.0

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 (260) hide show
  1. data/lib/vulcan/cli.rb +20 -10
  2. data/lib/vulcan/version.rb +1 -1
  3. data/server/Procfile +1 -1
  4. data/server/bin/web +10 -0
  5. data/server/lib/cloudant.coffee +20 -0
  6. data/server/lib/logger.coffee +17 -0
  7. data/server/lib/on.coffee +10 -0
  8. data/server/lib/spawner.coffee +65 -0
  9. data/server/node_modules/coffee-script/CNAME +1 -0
  10. data/server/node_modules/coffee-script/LICENSE +22 -0
  11. data/server/node_modules/coffee-script/README +51 -0
  12. data/server/node_modules/coffee-script/Rakefile +78 -0
  13. data/server/node_modules/coffee-script/bin/cake +7 -0
  14. data/server/node_modules/coffee-script/bin/coffee +7 -0
  15. data/server/node_modules/coffee-script/extras/jsl.conf +44 -0
  16. data/server/node_modules/coffee-script/lib/coffee-script/browser.js +92 -0
  17. data/server/node_modules/coffee-script/lib/coffee-script/cake.js +111 -0
  18. data/server/node_modules/coffee-script/lib/coffee-script/coffee-script.js +167 -0
  19. data/server/node_modules/coffee-script/lib/coffee-script/command.js +500 -0
  20. data/server/node_modules/coffee-script/lib/coffee-script/grammar.js +606 -0
  21. data/server/node_modules/coffee-script/lib/coffee-script/helpers.js +77 -0
  22. data/server/node_modules/coffee-script/lib/coffee-script/index.js +11 -0
  23. data/server/node_modules/coffee-script/lib/coffee-script/lexer.js +788 -0
  24. data/server/node_modules/coffee-script/lib/coffee-script/nodes.js +2986 -0
  25. data/server/node_modules/coffee-script/lib/coffee-script/optparse.js +138 -0
  26. data/server/node_modules/coffee-script/lib/coffee-script/parser.js +683 -0
  27. data/server/node_modules/coffee-script/lib/coffee-script/repl.js +261 -0
  28. data/server/node_modules/coffee-script/lib/coffee-script/rewriter.js +349 -0
  29. data/server/node_modules/coffee-script/lib/coffee-script/scope.js +146 -0
  30. data/server/node_modules/coffee-script/package.json +55 -0
  31. data/server/node_modules/connect-form/History.md +0 -6
  32. data/server/node_modules/connect-form/lib/connect-form.js +2 -4
  33. data/server/node_modules/connect-form/node_modules/formidable/Readme.md +64 -36
  34. data/server/node_modules/connect-form/node_modules/formidable/lib/incoming_form.js +5 -1
  35. data/server/node_modules/connect-form/node_modules/formidable/package.json +20 -6
  36. data/server/node_modules/connect-form/node_modules/formidable/test/common.js +5 -6
  37. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/file/funkyfilename.txt +1 -0
  38. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/js/special-chars-in-filename.js +1 -1
  39. data/server/node_modules/connect-form/node_modules/formidable/test/{slow → integration}/test-fixtures.js +38 -33
  40. data/server/node_modules/connect-form/node_modules/formidable/test/legacy/simple/test-incoming-form.js +11 -0
  41. data/server/node_modules/connect-form/node_modules/formidable/test/run.js +1 -6
  42. data/server/node_modules/connect-form/node_modules/formidable/test/unit/test-incoming-form.js +63 -0
  43. data/server/node_modules/connect-form/package.json +27 -5
  44. data/server/node_modules/cradle/README.md +10 -10
  45. data/server/node_modules/cradle/lib/cradle.js +117 -523
  46. data/server/node_modules/cradle/lib/cradle/database/attachments.js +120 -0
  47. data/server/node_modules/cradle/lib/cradle/database/changes.js +56 -0
  48. data/server/node_modules/cradle/lib/cradle/database/documents.js +215 -0
  49. data/server/node_modules/cradle/lib/cradle/database/index.js +65 -0
  50. data/server/node_modules/cradle/lib/cradle/database/views.js +125 -0
  51. data/server/node_modules/cradle/node_modules/follow/LICENSE +202 -0
  52. data/server/node_modules/cradle/node_modules/follow/README.md +164 -0
  53. data/server/node_modules/cradle/node_modules/follow/Rakefile +54 -0
  54. data/server/node_modules/cradle/node_modules/follow/api.js +35 -0
  55. data/server/node_modules/cradle/node_modules/follow/browser/eventemitter2.js +453 -0
  56. data/server/node_modules/cradle/node_modules/follow/browser/export.js +78 -0
  57. data/server/node_modules/cradle/node_modules/follow/browser/index.html +14 -0
  58. data/server/node_modules/cradle/node_modules/follow/browser/jquery-1.6.1.min.js +18 -0
  59. data/server/node_modules/cradle/node_modules/follow/browser/log4js.js +46 -0
  60. data/server/node_modules/cradle/node_modules/follow/browser/main.js +92 -0
  61. data/server/node_modules/cradle/node_modules/follow/browser/querystring.js +28 -0
  62. data/server/node_modules/cradle/node_modules/follow/browser/request.jquery.js +237 -0
  63. data/server/node_modules/cradle/node_modules/follow/browser/require.js +33 -0
  64. data/server/node_modules/cradle/node_modules/follow/browser/util.js +28 -0
  65. data/server/node_modules/cradle/node_modules/follow/cli.js +101 -0
  66. data/server/node_modules/cradle/node_modules/follow/lib/feed.js +556 -0
  67. data/server/node_modules/cradle/node_modules/follow/lib/index.js +66 -0
  68. data/server/node_modules/cradle/node_modules/follow/lib/stream.js +305 -0
  69. data/server/node_modules/cradle/node_modules/follow/node_modules/request/LICENSE +55 -0
  70. data/server/node_modules/cradle/node_modules/follow/node_modules/request/README.md +285 -0
  71. data/server/node_modules/cradle/node_modules/follow/node_modules/request/main.js +618 -0
  72. data/server/node_modules/cradle/node_modules/follow/node_modules/request/mimetypes.js +146 -0
  73. data/server/node_modules/cradle/node_modules/follow/node_modules/request/oauth.js +34 -0
  74. data/server/node_modules/cradle/node_modules/follow/node_modules/request/package.json +42 -0
  75. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/googledoodle.png +0 -0
  76. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/run.sh +6 -0
  77. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/server.js +57 -0
  78. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-body.js +90 -0
  79. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-cookie.js +29 -0
  80. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-cookiejar.js +90 -0
  81. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-errors.js +30 -0
  82. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-oauth.js +109 -0
  83. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-pipes.js +167 -0
  84. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-proxy.js +39 -0
  85. data/server/node_modules/cradle/node_modules/follow/node_modules/request/tests/test-timeout.js +87 -0
  86. data/server/node_modules/cradle/node_modules/follow/node_modules/request/uuid.js +19 -0
  87. data/server/node_modules/cradle/node_modules/follow/node_modules/request/vendor/cookie/index.js +55 -0
  88. data/server/node_modules/cradle/node_modules/follow/node_modules/request/vendor/cookie/jar.js +72 -0
  89. data/server/node_modules/cradle/node_modules/follow/package.json +45 -0
  90. data/server/node_modules/cradle/node_modules/follow/test/couch.js +153 -0
  91. data/server/node_modules/cradle/node_modules/follow/test/follow.js +136 -0
  92. data/server/node_modules/cradle/node_modules/follow/test/issues.js +178 -0
  93. data/server/node_modules/cradle/node_modules/follow/test/issues/10.js +24 -0
  94. data/server/node_modules/cradle/node_modules/follow/test/stream.js +493 -0
  95. data/server/node_modules/cradle/node_modules/request/LICENSE +55 -0
  96. data/server/node_modules/cradle/node_modules/request/README.md +287 -0
  97. data/server/node_modules/cradle/node_modules/request/forever.js +103 -0
  98. data/server/node_modules/cradle/node_modules/request/main.js +913 -0
  99. data/server/node_modules/cradle/node_modules/request/mimetypes.js +152 -0
  100. data/server/node_modules/cradle/node_modules/request/oauth.js +34 -0
  101. data/server/node_modules/cradle/node_modules/request/package.json +42 -0
  102. data/server/node_modules/cradle/node_modules/request/tests/googledoodle.png +0 -0
  103. data/server/node_modules/cradle/node_modules/request/tests/run.js +38 -0
  104. data/server/node_modules/cradle/node_modules/request/tests/server.js +82 -0
  105. data/server/node_modules/cradle/node_modules/request/tests/squid.conf +77 -0
  106. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/ca.cnf +20 -0
  107. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/ca.crl +0 -0
  108. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/ca.crt +17 -0
  109. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/ca.csr +13 -0
  110. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/ca.key +18 -0
  111. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/ca.srl +1 -0
  112. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/server.cnf +19 -0
  113. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/server.crt +16 -0
  114. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/server.csr +11 -0
  115. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/server.js +28 -0
  116. data/server/node_modules/cradle/node_modules/request/tests/ssl/ca/server.key +9 -0
  117. data/server/node_modules/cradle/node_modules/request/tests/ssl/npm-ca.crt +16 -0
  118. data/server/node_modules/cradle/node_modules/request/tests/ssl/test.crt +15 -0
  119. data/server/node_modules/cradle/node_modules/request/tests/ssl/test.key +15 -0
  120. data/server/node_modules/cradle/node_modules/request/tests/test-body.js +95 -0
  121. data/server/node_modules/cradle/node_modules/request/tests/test-cookie.js +29 -0
  122. data/server/node_modules/cradle/node_modules/request/tests/test-cookiejar.js +90 -0
  123. data/server/node_modules/cradle/node_modules/request/tests/test-defaults.js +68 -0
  124. data/server/node_modules/cradle/node_modules/request/tests/test-errors.js +37 -0
  125. data/server/node_modules/cradle/node_modules/request/tests/test-headers.js +52 -0
  126. data/server/node_modules/cradle/node_modules/request/tests/test-httpModule.js +94 -0
  127. data/server/node_modules/cradle/node_modules/request/tests/test-https-strict.js +97 -0
  128. data/server/node_modules/cradle/node_modules/request/tests/test-https.js +86 -0
  129. data/server/node_modules/cradle/node_modules/request/tests/test-oauth.js +117 -0
  130. data/server/node_modules/cradle/node_modules/request/tests/test-params.js +92 -0
  131. data/server/node_modules/cradle/node_modules/request/tests/test-pipes.js +202 -0
  132. data/server/node_modules/cradle/node_modules/request/tests/test-proxy.js +39 -0
  133. data/server/node_modules/cradle/node_modules/request/tests/test-qs.js +28 -0
  134. data/server/node_modules/cradle/node_modules/request/tests/test-redirect.js +154 -0
  135. data/server/node_modules/cradle/node_modules/request/tests/test-timeout.js +87 -0
  136. data/server/node_modules/cradle/node_modules/request/tests/test-toJSON.js +14 -0
  137. data/server/node_modules/cradle/node_modules/request/tests/test-tunnel.js +61 -0
  138. data/server/node_modules/cradle/node_modules/request/tunnel.js +229 -0
  139. data/server/node_modules/cradle/node_modules/request/uuid.js +19 -0
  140. data/server/node_modules/cradle/node_modules/request/vendor/cookie/index.js +65 -0
  141. data/server/node_modules/cradle/node_modules/request/vendor/cookie/jar.js +72 -0
  142. data/server/node_modules/cradle/node_modules/vargs/package.json +33 -10
  143. data/server/node_modules/cradle/package.json +50 -12
  144. data/server/node_modules/cradle/test/cache-test.js +1 -4
  145. data/server/node_modules/cradle/test/connection-test.js +179 -0
  146. data/server/node_modules/cradle/test/database-attachment-test.js +344 -0
  147. data/server/node_modules/cradle/test/database-cache-test.js +132 -0
  148. data/server/node_modules/cradle/test/database-test.js +219 -0
  149. data/server/node_modules/cradle/test/database-view-test.js +141 -0
  150. data/server/node_modules/cradle/test/fixtures/databases.json +28 -1
  151. data/server/node_modules/cradle/test/helpers/seed.js +14 -5
  152. data/server/node_modules/cradle/test/response-test.js +1 -1
  153. data/server/node_modules/express/History.md +16 -0
  154. data/server/node_modules/express/bin/express +7 -6
  155. data/server/node_modules/express/lib-cov/application.js +510 -0
  156. data/server/node_modules/express/lib-cov/express.js +65 -0
  157. data/server/node_modules/express/lib-cov/middleware.js +54 -0
  158. data/server/node_modules/express/lib-cov/request.js +225 -0
  159. data/server/node_modules/express/lib-cov/response.js +611 -0
  160. data/server/node_modules/express/lib-cov/router/collection.js +40 -0
  161. data/server/node_modules/express/lib-cov/router/index.js +515 -0
  162. data/server/node_modules/express/lib-cov/router/methods.js +9 -0
  163. data/server/node_modules/express/lib-cov/router/route.js +68 -0
  164. data/server/node_modules/express/lib-cov/utils.js +151 -0
  165. data/server/node_modules/express/lib-cov/view.js +81 -0
  166. data/server/node_modules/express/lib/express.js +1 -1
  167. data/server/node_modules/express/lib/http.js +1 -2
  168. data/server/node_modules/express/lib/request.js +2 -2
  169. data/server/node_modules/express/lib/router/methods.js +10 -1
  170. data/server/node_modules/express/node_modules/connect/lib/connect.js +1 -1
  171. data/server/node_modules/express/node_modules/connect/lib/http.js +3 -2
  172. data/server/node_modules/express/node_modules/connect/lib/middleware/limit.js +0 -2
  173. data/server/node_modules/express/node_modules/connect/lib/middleware/session.js +1 -2
  174. data/server/node_modules/express/node_modules/connect/node_modules/formidable/Readme.md +42 -25
  175. data/server/node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js +1 -0
  176. data/server/node_modules/express/node_modules/connect/node_modules/formidable/package.json +14 -3
  177. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js +11 -0
  178. data/server/node_modules/express/node_modules/connect/package.json +35 -7
  179. data/server/node_modules/express/node_modules/mime/package.json +30 -8
  180. data/server/node_modules/express/node_modules/mkdirp/README.markdown +35 -2
  181. data/server/node_modules/express/node_modules/mkdirp/examples/pow.js +1 -1
  182. data/server/node_modules/express/node_modules/mkdirp/index.js +72 -13
  183. data/server/node_modules/express/node_modules/mkdirp/package.json +39 -21
  184. data/server/node_modules/express/node_modules/mkdirp/test/chmod.js +38 -0
  185. data/server/node_modules/express/node_modules/mkdirp/test/clobber.js +37 -0
  186. data/server/node_modules/express/node_modules/mkdirp/test/perm.js +32 -0
  187. data/server/node_modules/express/node_modules/mkdirp/test/perm_sync.js +39 -0
  188. data/server/node_modules/express/node_modules/mkdirp/test/sync.js +27 -0
  189. data/server/node_modules/express/node_modules/mkdirp/test/umask.js +28 -0
  190. data/server/node_modules/express/node_modules/mkdirp/test/umask_sync.js +27 -0
  191. data/server/node_modules/express/node_modules/qs/History.md +10 -0
  192. data/server/node_modules/express/node_modules/qs/Readme.md +9 -2
  193. data/server/node_modules/express/node_modules/qs/examples.js +3 -0
  194. data/server/node_modules/express/node_modules/qs/lib/querystring.js +8 -6
  195. data/server/node_modules/express/node_modules/qs/package.json +26 -8
  196. data/server/node_modules/express/node_modules/qs/test/parse.js +13 -1
  197. data/server/node_modules/express/node_modules/qs/test/stringify.js +45 -37
  198. data/server/node_modules/express/package.json +55 -16
  199. data/server/node_modules/express/test.js +41 -0
  200. data/server/node_modules/knox/package.json +26 -4
  201. data/server/node_modules/node-uuid/package.json +40 -11
  202. data/server/node_modules/node-uuid/test/test.js +1 -1
  203. data/server/node_modules/nodemon/README.md +120 -0
  204. data/server/node_modules/nodemon/nodemon.js +518 -0
  205. data/server/node_modules/nodemon/nodemonignore.example +11 -0
  206. data/server/node_modules/nodemon/package.json +49 -0
  207. data/server/node_modules/restler/README.md +144 -94
  208. data/server/node_modules/restler/lib/multipartform.js +2 -0
  209. data/server/node_modules/restler/lib/restler.js +218 -61
  210. data/server/node_modules/restler/package.json +35 -8
  211. data/server/node_modules/restler/test/all.js +6 -1
  212. data/server/node_modules/restler/test/restler.js +624 -118
  213. data/server/package.json +14 -10
  214. data/server/web.coffee +64 -0
  215. data/server/web.js +15 -3
  216. metadata +170 -57
  217. data/server/index.js +0 -14
  218. data/server/node_modules/connect-form/LICENSE +0 -22
  219. data/server/node_modules/connect-form/index.js +0 -100
  220. data/server/node_modules/connect-form/node_modules/formidable/test/fast/test-incoming-form.js +0 -45
  221. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/no-filename/generic.http +0 -13
  222. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-chrome-13.http +0 -26
  223. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-firefox-3.6.http +0 -24
  224. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-safari-5.http +0 -23
  225. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-chrome-12.http +0 -24
  226. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-ie-7.http +0 -22
  227. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-ie-8.http +0 -22
  228. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-safari-5.http +0 -22
  229. data/server/node_modules/connect-form/node_modules/formidable/test/fixture/multi_video.upload +0 -0
  230. data/server/node_modules/cradle/Makefile +0 -10
  231. data/server/node_modules/cradle/test/cradle-test.js +0 -650
  232. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/no-filename/generic.http +0 -13
  233. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-chrome-13.http +0 -26
  234. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-firefox-3.6.http +0 -24
  235. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/osx-safari-5.http +0 -23
  236. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-chrome-12.http +0 -24
  237. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-ie-7.http +0 -22
  238. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-ie-8.http +0 -22
  239. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/xp-safari-5.http +0 -22
  240. data/server/node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/multi_video.upload +0 -0
  241. data/server/node_modules/express/node_modules/connect/test.js +0 -52
  242. data/server/node_modules/express/testing/foo/app.js +0 -35
  243. data/server/node_modules/express/testing/foo/package.json +0 -9
  244. data/server/node_modules/express/testing/foo/public/stylesheets/style.css +0 -8
  245. data/server/node_modules/express/testing/foo/routes/index.js +0 -10
  246. data/server/node_modules/express/testing/foo/views/index.jade +0 -2
  247. data/server/node_modules/express/testing/foo/views/layout.jade +0 -6
  248. data/server/node_modules/express/testing/index.js +0 -43
  249. data/server/node_modules/express/testing/public/test.txt +0 -2971
  250. data/server/node_modules/express/testing/views/page.html +0 -1
  251. data/server/node_modules/express/testing/views/page.jade +0 -3
  252. data/server/node_modules/express/testing/views/test.md +0 -1
  253. data/server/node_modules/express/testing/views/user/index.jade +0 -1
  254. data/server/node_modules/express/testing/views/user/list.jade +0 -1
  255. data/server/node_modules/knox/lib/knox/mime/index.js +0 -308
  256. data/server/node_modules/knox/lib/knox/mime/test.js +0 -59
  257. data/server/node_modules/node-uuid/test/benchmark-native +0 -0
  258. data/server/node_modules/on/index.js +0 -13
  259. data/server/node_modules/restler/test/test_helper.js +0 -163
  260. data/server/node_modules/spawner/index.js +0 -106
@@ -0,0 +1,618 @@
1
+ // Copyright 2010-2011 Mikeal Rogers
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ var http = require('http')
16
+ , https = false
17
+ , tls = false
18
+ , url = require('url')
19
+ , util = require('util')
20
+ , stream = require('stream')
21
+ , qs = require('querystring')
22
+ , mimetypes = require('./mimetypes')
23
+ , oauth = require('./oauth')
24
+ , uuid = require('./uuid')
25
+ , Cookie = require('./vendor/cookie')
26
+ , CookieJar = require('./vendor/cookie/jar')
27
+ , cookieJar = new CookieJar
28
+ ;
29
+
30
+ try {
31
+ https = require('https')
32
+ } catch (e) {}
33
+
34
+ try {
35
+ tls = require('tls')
36
+ } catch (e) {}
37
+
38
+ function toBase64 (str) {
39
+ return (new Buffer(str || "", "ascii")).toString("base64")
40
+ }
41
+
42
+ // Hacky fix for pre-0.4.4 https
43
+ if (https && !https.Agent) {
44
+ https.Agent = function (options) {
45
+ http.Agent.call(this, options)
46
+ }
47
+ util.inherits(https.Agent, http.Agent)
48
+ https.Agent.prototype._getConnection = function(host, port, cb) {
49
+ var s = tls.connect(port, host, this.options, function() {
50
+ // do other checks here?
51
+ if (cb) cb()
52
+ })
53
+ return s
54
+ }
55
+ }
56
+
57
+ function isReadStream (rs) {
58
+ if (rs.readable && rs.path && rs.mode) {
59
+ return true
60
+ }
61
+ }
62
+
63
+ function copy (obj) {
64
+ var o = {}
65
+ for (var i in obj) o[i] = obj[i]
66
+ return o
67
+ }
68
+
69
+ var isUrl = /^https?:/
70
+
71
+ var globalPool = {}
72
+
73
+ function Request (options) {
74
+ stream.Stream.call(this)
75
+ this.readable = true
76
+ this.writable = true
77
+
78
+ if (typeof options === 'string') {
79
+ options = {uri:options}
80
+ }
81
+
82
+ for (var i in options) {
83
+ this[i] = options[i]
84
+ }
85
+ if (!this.pool) this.pool = globalPool
86
+ this.dests = []
87
+ this.__isRequestRequest = true
88
+ }
89
+ util.inherits(Request, stream.Stream)
90
+ Request.prototype.getAgent = function (host, port) {
91
+ if (!this.pool[host+':'+port]) {
92
+ this.pool[host+':'+port] = new this.httpModule.Agent({host:host, port:port})
93
+ }
94
+ return this.pool[host+':'+port]
95
+ }
96
+ Request.prototype.request = function () {
97
+ var self = this
98
+
99
+ // Protect against double callback
100
+ if (!self._callback && self.callback) {
101
+ self._callback = self.callback
102
+ self.callback = function () {
103
+ if (self._callbackCalled) return // Print a warning maybe?
104
+ self._callback.apply(self, arguments)
105
+ self._callbackCalled = true
106
+ }
107
+ }
108
+
109
+ if (self.url) {
110
+ // People use this property instead all the time so why not just support it.
111
+ self.uri = self.url
112
+ delete self.url
113
+ }
114
+
115
+ if (!self.uri) {
116
+ throw new Error("options.uri is a required argument")
117
+ } else {
118
+ if (typeof self.uri == "string") self.uri = url.parse(self.uri)
119
+ }
120
+ if (self.proxy) {
121
+ if (typeof self.proxy == 'string') self.proxy = url.parse(self.proxy)
122
+ }
123
+
124
+ self._redirectsFollowed = self._redirectsFollowed || 0
125
+ self.maxRedirects = (self.maxRedirects !== undefined) ? self.maxRedirects : 10
126
+ self.followRedirect = (self.followRedirect !== undefined) ? self.followRedirect : true
127
+ if (self.followRedirect)
128
+ self.redirects = self.redirects || []
129
+
130
+ self.headers = self.headers ? copy(self.headers) : {}
131
+
132
+ var setHost = false
133
+ if (!self.headers.host) {
134
+ self.headers.host = self.uri.hostname
135
+ if (self.uri.port) {
136
+ if ( !(self.uri.port === 80 && self.uri.protocol === 'http:') &&
137
+ !(self.uri.port === 443 && self.uri.protocol === 'https:') )
138
+ self.headers.host += (':'+self.uri.port)
139
+ }
140
+ setHost = true
141
+ }
142
+
143
+ if (self.jar === false) {
144
+ // disable cookies
145
+ var cookies = false;
146
+ self._disableCookies = true;
147
+ } else if (self.jar) {
148
+ // fetch cookie from the user defined cookie jar
149
+ var cookies = self.jar.get({ url: self.uri.href })
150
+ } else {
151
+ // fetch cookie from the global cookie jar
152
+ var cookies = cookieJar.get({ url: self.uri.href })
153
+ }
154
+ if (cookies) {
155
+ var cookieString = cookies.map(function (c) {
156
+ return c.name + "=" + c.value;
157
+ }).join("; ");
158
+
159
+ self.headers.Cookie = cookieString;
160
+ }
161
+
162
+ if (!self.uri.pathname) {self.uri.pathname = '/'}
163
+ if (!self.uri.port) {
164
+ if (self.uri.protocol == 'http:') {self.uri.port = 80}
165
+ else if (self.uri.protocol == 'https:') {self.uri.port = 443}
166
+ }
167
+
168
+ if (self.proxy) {
169
+ self.port = self.proxy.port
170
+ self.host = self.proxy.hostname
171
+ } else {
172
+ self.port = self.uri.port
173
+ self.host = self.uri.hostname
174
+ }
175
+
176
+ if (self.onResponse === true) {
177
+ self.onResponse = self.callback
178
+ delete self.callback
179
+ }
180
+
181
+ var clientErrorHandler = function (error) {
182
+ if (setHost) delete self.headers.host
183
+ if (self.timeout && self.timeoutTimer) clearTimeout(self.timeoutTimer)
184
+ self.emit('error', error)
185
+ }
186
+ if (self.onResponse) self.on('error', function (e) {self.onResponse(e)})
187
+ if (self.callback) self.on('error', function (e) {self.callback(e)})
188
+
189
+ if (self.form) {
190
+ self.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8'
191
+ self.body = qs.stringify(self.form).toString('utf8')
192
+ }
193
+
194
+ if (self.oauth) {
195
+ var form
196
+ if (self.headers['content-type'] &&
197
+ self.headers['content-type'].slice(0, 'application/x-www-form-urlencoded'.length) ===
198
+ 'application/x-www-form-urlencoded'
199
+ ) {
200
+ form = qs.parse(self.body)
201
+ }
202
+ if (self.uri.query) {
203
+ form = qs.parse(self.uri.query)
204
+ }
205
+ if (!form) form = {}
206
+ var oa = {}
207
+ for (var i in form) oa[i] = form[i]
208
+ for (var i in self.oauth) oa['oauth_'+i] = self.oauth[i]
209
+ if (!oa.oauth_version) oa.oauth_version = '1.0'
210
+ if (!oa.oauth_timestamp) oa.oauth_timestamp = Math.floor( (new Date()).getTime() / 1000 ).toString()
211
+ if (!oa.oauth_nonce) oa.oauth_nonce = uuid().replace(/-/g, '')
212
+
213
+ oa.oauth_signature_method = 'HMAC-SHA1'
214
+
215
+ var consumer_secret = oa.oauth_consumer_secret
216
+ delete oa.oauth_consumer_secret
217
+ var token_secret = oa.oauth_token_secret
218
+ delete oa.oauth_token_secret
219
+
220
+ var baseurl = self.uri.protocol + '//' + self.uri.host + self.uri.pathname
221
+ var signature = oauth.hmacsign(self.method, baseurl, oa, consumer_secret, token_secret)
222
+
223
+ // oa.oauth_signature = signature
224
+ for (var i in form) {
225
+ if ( i.slice(0, 'oauth_') in self.oauth) {
226
+ // skip
227
+ } else {
228
+ delete oa['oauth_'+i]
229
+ }
230
+ }
231
+ self.headers.authorization =
232
+ 'OAuth '+Object.keys(oa).sort().map(function (i) {return i+'="'+oauth.rfc3986(oa[i])+'"'}).join(',')
233
+ self.headers.authorization += ',oauth_signature="'+oauth.rfc3986(signature)+'"'
234
+ }
235
+
236
+ if (self.uri.auth && !self.headers.authorization) {
237
+ self.headers.authorization = "Basic " + toBase64(self.uri.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':'))
238
+ }
239
+ if (self.proxy && self.proxy.auth && !self.headers['proxy-authorization']) {
240
+ self.headers['proxy-authorization'] = "Basic " + toBase64(self.proxy.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':'))
241
+ }
242
+
243
+ if (self.uri.path) {
244
+ self.path = self.uri.path
245
+ } else {
246
+ self.path = self.uri.pathname + (self.uri.search || "")
247
+ }
248
+
249
+ if (self.path.length === 0) self.path = '/'
250
+
251
+ if (self.proxy) self.path = (self.uri.protocol + '//' + self.uri.host + self.path)
252
+
253
+ if (self.json) {
254
+ self.headers['content-type'] = 'application/json'
255
+ if (typeof self.json === 'boolean') {
256
+ if (typeof self.body === 'object') self.body = JSON.stringify(self.body)
257
+ } else {
258
+ self.body = JSON.stringify(self.json)
259
+ }
260
+
261
+ } else if (self.multipart) {
262
+ self.body = [];
263
+ self.headers['content-type'] = 'multipart/related;boundary="frontier"'
264
+ if (!self.multipart.forEach) throw new Error('Argument error, options.multipart.')
265
+
266
+ self.multipart.forEach(function (part) {
267
+ var body = part.body
268
+ if(!body) throw Error('Body attribute missing in multipart.')
269
+ delete part.body
270
+ var preamble = '--frontier\r\n'
271
+ Object.keys(part).forEach(function(key){
272
+ preamble += key + ': ' + part[key] + '\r\n'
273
+ })
274
+ preamble += '\r\n';
275
+ self.body.push(new Buffer(preamble));
276
+ self.body.push(new Buffer(body));
277
+ self.body.push(new Buffer('\r\n'));
278
+ })
279
+ self.body.push(new Buffer('--frontier--'));
280
+ }
281
+
282
+ if (self.body) {
283
+ var length = 0;
284
+ if (!Buffer.isBuffer(self.body)) {
285
+ if (Array.isArray(self.body)) {
286
+ for (var i = 0; i < self.body.length; i++) {
287
+ length += self.body[i].length;
288
+ }
289
+ } else {
290
+ self.body = new Buffer(self.body)
291
+ length = self.body.length;
292
+ }
293
+ } else {
294
+ length = self.body.length;
295
+ }
296
+ if (length) {
297
+ self.headers['content-length'] = length;
298
+ } else {
299
+ throw new Error('Argument error, options.body.')
300
+ }
301
+ }
302
+
303
+ self.httpModule =
304
+ {"http:":http, "https:":https}[self.proxy ? self.proxy.protocol : self.uri.protocol]
305
+
306
+ if (!self.httpModule) throw new Error("Invalid protocol")
307
+
308
+ if (self.pool === false) {
309
+ self.agent = false
310
+ } else {
311
+ if (self.maxSockets) {
312
+ // Don't use our pooling if node has the refactored client
313
+ self.agent = self.httpModule.globalAgent || self.getAgent(self.host, self.port)
314
+ self.agent.maxSockets = self.maxSockets
315
+ }
316
+ if (self.pool.maxSockets) {
317
+ // Don't use our pooling if node has the refactored client
318
+ self.agent = self.httpModule.globalAgent || self.getAgent(self.host, self.port)
319
+ self.agent.maxSockets = self.pool.maxSockets
320
+ }
321
+ }
322
+
323
+ self.start = function () {
324
+ self._started = true
325
+ self.method = self.method || 'GET'
326
+
327
+ self.req = self.httpModule.request(self, function (response) {
328
+ self.response = response
329
+ response.request = self
330
+
331
+ if (self.httpModule === https &&
332
+ self.strictSSL &&
333
+ !response.client.authorized) {
334
+ var sslErr = response.client.authorizationError
335
+ self.emit('error', new Error('SSL Error: '+ sslErr))
336
+ return
337
+ }
338
+
339
+ if (setHost) delete self.headers.host
340
+ if (self.timeout && self.timeoutTimer) clearTimeout(self.timeoutTimer)
341
+
342
+ if (response.headers['set-cookie'] && (!self._disableCookies)) {
343
+ response.headers['set-cookie'].forEach(function(cookie) {
344
+ if (self.jar) {
345
+ // custom defined jar
346
+ self.jar.add(new Cookie(cookie));
347
+ }
348
+ else {
349
+ // add to the global cookie jar if user don't define his own
350
+ cookieJar.add(new Cookie(cookie));
351
+ }
352
+ });
353
+ }
354
+
355
+ if (response.statusCode >= 300 &&
356
+ response.statusCode < 400 &&
357
+ self.followRedirect &&
358
+ self.method !== 'PUT' &&
359
+ self.method !== 'POST' &&
360
+ response.headers.location) {
361
+ if (self._redirectsFollowed >= self.maxRedirects) {
362
+ self.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop."))
363
+ return
364
+ }
365
+ self._redirectsFollowed += 1
366
+
367
+ if (!isUrl.test(response.headers.location)) {
368
+ response.headers.location = url.resolve(self.uri.href, response.headers.location)
369
+ }
370
+ self.uri = response.headers.location
371
+ self.redirects.push( { statusCode : response.statusCode,
372
+ redirectUri: response.headers.location })
373
+ delete self.req
374
+ delete self.agent
375
+ delete self._started
376
+ if (self.headers) {
377
+ delete self.headers.host
378
+ }
379
+ request(self, self.callback)
380
+ return // Ignore the rest of the response
381
+ } else {
382
+ self._redirectsFollowed = self._redirectsFollowed || 0
383
+ // Be a good stream and emit end when the response is finished.
384
+ // Hack to emit end on close because of a core bug that never fires end
385
+ response.on('close', function () {
386
+ if (!self._ended) self.response.emit('end')
387
+ })
388
+
389
+ if (self.encoding) {
390
+ if (self.dests.length !== 0) {
391
+ console.error("Ingoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.")
392
+ } else {
393
+ response.setEncoding(self.encoding)
394
+ }
395
+ }
396
+
397
+ self.pipeDest = function (dest) {
398
+ if (dest.headers) {
399
+ dest.headers['content-type'] = response.headers['content-type']
400
+ if (response.headers['content-length']) {
401
+ dest.headers['content-length'] = response.headers['content-length']
402
+ }
403
+ }
404
+ if (dest.setHeader) {
405
+ for (var i in response.headers) {
406
+ dest.setHeader(i, response.headers[i])
407
+ }
408
+ dest.statusCode = response.statusCode
409
+ }
410
+ if (self.pipefilter) self.pipefilter(response, dest)
411
+ }
412
+
413
+ self.dests.forEach(function (dest) {
414
+ self.pipeDest(dest)
415
+ })
416
+
417
+ response.on("data", function (chunk) {
418
+ self._destdata = true
419
+ self.emit("data", chunk)
420
+ })
421
+ response.on("end", function (chunk) {
422
+ self._ended = true
423
+ self.emit("end", chunk)
424
+ })
425
+ response.on("close", function () {self.emit("close")})
426
+
427
+ self.emit('response', response)
428
+
429
+ if (self.onResponse) {
430
+ self.onResponse(null, response)
431
+ }
432
+ if (self.callback) {
433
+ var buffer = []
434
+ var bodyLen = 0
435
+ self.on("data", function (chunk) {
436
+ buffer.push(chunk)
437
+ bodyLen += chunk.length
438
+ })
439
+ self.on("end", function () {
440
+ if (buffer.length && Buffer.isBuffer(buffer[0])) {
441
+ var body = new Buffer(bodyLen)
442
+ var i = 0
443
+ buffer.forEach(function (chunk) {
444
+ chunk.copy(body, i, 0, chunk.length)
445
+ i += chunk.length
446
+ })
447
+ response.body = body.toString()
448
+ } else if (buffer.length) {
449
+ response.body = buffer.join('')
450
+ }
451
+
452
+ if (self.json) {
453
+ try {
454
+ response.body = JSON.parse(response.body)
455
+ } catch (e) {}
456
+ }
457
+
458
+ self.callback(null, response, response.body)
459
+ })
460
+ }
461
+ }
462
+ })
463
+
464
+ if (self.timeout) {
465
+ self.timeoutTimer = setTimeout(function() {
466
+ self.req.abort()
467
+ var e = new Error("ETIMEDOUT")
468
+ e.code = "ETIMEDOUT"
469
+ self.emit("error", e)
470
+ }, self.timeout)
471
+ }
472
+
473
+ self.req.on('error', clientErrorHandler)
474
+ }
475
+
476
+ self.once('pipe', function (src) {
477
+ if (self.ntick) throw new Error("You cannot pipe to this stream after the first nextTick() after creation of the request stream.")
478
+ self.src = src
479
+ if (isReadStream(src)) {
480
+ if (!self.headers['content-type'] && !self.headers['Content-Type'])
481
+ self.headers['content-type'] = mimetypes.lookup(src.path.slice(src.path.lastIndexOf('.')+1))
482
+ } else {
483
+ if (src.headers) {
484
+ for (var i in src.headers) {
485
+ if (!self.headers[i]) {
486
+ self.headers[i] = src.headers[i]
487
+ }
488
+ }
489
+ }
490
+ if (src.method && !self.method) {
491
+ self.method = src.method
492
+ }
493
+ }
494
+
495
+ self.on('pipe', function () {
496
+ console.error("You have already piped to this stream. Pipeing twice is likely to break the request.")
497
+ })
498
+ })
499
+
500
+ process.nextTick(function () {
501
+ if (self.body) {
502
+ if (Array.isArray(self.body)) {
503
+ self.body.forEach(function(part) {
504
+ self.write(part);
505
+ });
506
+ } else {
507
+ self.write(self.body)
508
+ }
509
+ self.end()
510
+ } else if (self.requestBodyStream) {
511
+ console.warn("options.requestBodyStream is deprecated, please pass the request object to stream.pipe.")
512
+ self.requestBodyStream.pipe(self)
513
+ } else if (!self.src) {
514
+ self.headers['content-length'] = 0
515
+ self.end()
516
+ }
517
+ self.ntick = true
518
+ })
519
+ }
520
+ Request.prototype.pipe = function (dest) {
521
+ if (this.response) {
522
+ if (this._destdata) {
523
+ throw new Error("You cannot pipe after data has been emitted from the response.")
524
+ } else if (this._ended) {
525
+ throw new Error("You cannot pipe after the response has been ended.")
526
+ } else {
527
+ stream.Stream.prototype.pipe.call(this, dest)
528
+ this.pipeDest(dest)
529
+ return dest
530
+ }
531
+ } else {
532
+ this.dests.push(dest)
533
+ stream.Stream.prototype.pipe.call(this, dest)
534
+ return dest
535
+ }
536
+ }
537
+ Request.prototype.write = function () {
538
+ if (!this._started) this.start()
539
+ if (!this.req) throw new Error("This request has been piped before http.request() was called.")
540
+ this.req.write.apply(this.req, arguments)
541
+ }
542
+ Request.prototype.end = function () {
543
+ if (!this._started) this.start()
544
+ if (!this.req) throw new Error("This request has been piped before http.request() was called.")
545
+ this.req.end.apply(this.req, arguments)
546
+ }
547
+ Request.prototype.pause = function () {
548
+ if (!this.response) throw new Error("This request has been piped before http.request() was called.")
549
+ this.response.pause.apply(this.response, arguments)
550
+ }
551
+ Request.prototype.resume = function () {
552
+ if (!this.response) throw new Error("This request has been piped before http.request() was called.")
553
+ this.response.resume.apply(this.response, arguments)
554
+ }
555
+
556
+ function request (options, callback) {
557
+ if (typeof options === 'string') options = {uri:options}
558
+ if (callback) options.callback = callback
559
+ var r = new Request(options)
560
+ r.request()
561
+ return r
562
+ }
563
+
564
+ module.exports = request
565
+
566
+ request.defaults = function (options) {
567
+ var def = function (method) {
568
+ var d = function (opts, callback) {
569
+ if (typeof opts === 'string') opts = {uri:opts}
570
+ for (var i in options) {
571
+ if (opts[i] === undefined) opts[i] = options[i]
572
+ }
573
+ return method(opts, callback)
574
+ }
575
+ return d
576
+ }
577
+ var de = def(request)
578
+ de.get = def(request.get)
579
+ de.post = def(request.post)
580
+ de.put = def(request.put)
581
+ de.head = def(request.head)
582
+ de.del = def(request.del)
583
+ de.cookie = def(request.cookie)
584
+ de.jar = def(request.jar)
585
+ return de
586
+ }
587
+
588
+ request.get = request
589
+ request.post = function (options, callback) {
590
+ if (typeof options === 'string') options = {uri:options}
591
+ options.method = 'POST'
592
+ return request(options, callback)
593
+ }
594
+ request.put = function (options, callback) {
595
+ if (typeof options === 'string') options = {uri:options}
596
+ options.method = 'PUT'
597
+ return request(options, callback)
598
+ }
599
+ request.head = function (options, callback) {
600
+ if (typeof options === 'string') options = {uri:options}
601
+ options.method = 'HEAD'
602
+ if (options.body || options.requestBodyStream || options.json || options.multipart) {
603
+ throw new Error("HTTP HEAD requests MUST NOT include a request body.")
604
+ }
605
+ return request(options, callback)
606
+ }
607
+ request.del = function (options, callback) {
608
+ if (typeof options === 'string') options = {uri:options}
609
+ options.method = 'DELETE'
610
+ return request(options, callback)
611
+ }
612
+ request.jar = function () {
613
+ return new CookieJar
614
+ }
615
+ request.cookie = function (str) {
616
+ if (typeof str !== 'string') throw new Error("The cookie function only accepts STRING as param")
617
+ return new Cookie(str)
618
+ }