es6-crawler-detect 3.1.1 → 3.3.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 (353) hide show
  1. package/.babelrc +2 -1
  2. package/.eslintignore +6 -0
  3. package/.eslintrc.json +30 -0
  4. package/.github/ISSUE_TEMPLATE/bug_report.md +11 -8
  5. package/.github/ISSUE_TEMPLATE/feature_request.md +1 -1
  6. package/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +29 -0
  7. package/.prettierrc.json +5 -0
  8. package/README.md +27 -17
  9. package/dist/main.bundle.js +1 -1
  10. package/example/node/dist/crawler.min.js +1 -1
  11. package/example/node/node_modules/.bin/mime +15 -0
  12. package/example/node/node_modules/.bin/mime.cmd +7 -0
  13. package/example/node/node_modules/.yarn-integrity +67 -0
  14. package/example/node/node_modules/accepts/HISTORY.md +236 -0
  15. package/example/node/node_modules/accepts/LICENSE +23 -0
  16. package/example/node/node_modules/accepts/README.md +142 -0
  17. package/example/node/node_modules/accepts/index.js +238 -0
  18. package/example/node/node_modules/accepts/package.json +47 -0
  19. package/example/node/node_modules/array-flatten/LICENSE +21 -0
  20. package/example/node/node_modules/array-flatten/README.md +43 -0
  21. package/example/node/node_modules/array-flatten/array-flatten.js +64 -0
  22. package/example/node/node_modules/array-flatten/package.json +39 -0
  23. package/example/node/node_modules/body-parser/HISTORY.md +624 -0
  24. package/example/node/node_modules/body-parser/LICENSE +23 -0
  25. package/example/node/node_modules/body-parser/README.md +456 -0
  26. package/example/node/node_modules/body-parser/index.js +157 -0
  27. package/example/node/node_modules/body-parser/lib/read.js +181 -0
  28. package/example/node/node_modules/body-parser/lib/types/json.js +230 -0
  29. package/example/node/node_modules/body-parser/lib/types/raw.js +101 -0
  30. package/example/node/node_modules/body-parser/lib/types/text.js +121 -0
  31. package/example/node/node_modules/body-parser/lib/types/urlencoded.js +284 -0
  32. package/example/node/node_modules/body-parser/package.json +52 -0
  33. package/example/node/node_modules/bytes/History.md +92 -0
  34. package/example/node/node_modules/bytes/LICENSE +23 -0
  35. package/example/node/node_modules/bytes/Readme.md +152 -0
  36. package/example/node/node_modules/bytes/index.js +166 -0
  37. package/example/node/node_modules/bytes/package.json +42 -0
  38. package/example/node/node_modules/content-disposition/HISTORY.md +60 -0
  39. package/example/node/node_modules/content-disposition/LICENSE +22 -0
  40. package/example/node/node_modules/content-disposition/README.md +142 -0
  41. package/example/node/node_modules/content-disposition/index.js +458 -0
  42. package/example/node/node_modules/content-disposition/package.json +44 -0
  43. package/example/node/node_modules/content-type/HISTORY.md +24 -0
  44. package/example/node/node_modules/content-type/LICENSE +22 -0
  45. package/example/node/node_modules/content-type/README.md +92 -0
  46. package/example/node/node_modules/content-type/index.js +222 -0
  47. package/example/node/node_modules/content-type/package.json +40 -0
  48. package/example/node/node_modules/cookie/HISTORY.md +128 -0
  49. package/example/node/node_modules/cookie/LICENSE +24 -0
  50. package/example/node/node_modules/cookie/README.md +257 -0
  51. package/example/node/node_modules/cookie/index.js +202 -0
  52. package/example/node/node_modules/cookie/package.json +40 -0
  53. package/example/node/node_modules/cookie-signature/History.md +38 -0
  54. package/example/node/node_modules/cookie-signature/Readme.md +42 -0
  55. package/example/node/node_modules/cookie-signature/index.js +51 -0
  56. package/example/node/node_modules/cookie-signature/package.json +18 -0
  57. package/example/node/node_modules/debug/.coveralls.yml +1 -0
  58. package/example/node/node_modules/debug/.eslintrc +11 -0
  59. package/example/node/node_modules/debug/.travis.yml +14 -0
  60. package/example/node/node_modules/debug/CHANGELOG.md +362 -0
  61. package/example/node/node_modules/debug/LICENSE +19 -0
  62. package/example/node/node_modules/debug/Makefile +50 -0
  63. package/example/node/node_modules/debug/README.md +312 -0
  64. package/example/node/node_modules/debug/component.json +19 -0
  65. package/example/node/node_modules/debug/karma.conf.js +70 -0
  66. package/example/node/node_modules/debug/node.js +1 -0
  67. package/example/node/node_modules/debug/package.json +49 -0
  68. package/example/node/node_modules/debug/src/browser.js +185 -0
  69. package/example/node/node_modules/debug/src/debug.js +202 -0
  70. package/example/node/node_modules/debug/src/index.js +10 -0
  71. package/example/node/node_modules/debug/src/inspector-log.js +15 -0
  72. package/example/node/node_modules/debug/src/node.js +248 -0
  73. package/example/node/node_modules/depd/History.md +96 -0
  74. package/example/node/node_modules/depd/LICENSE +22 -0
  75. package/example/node/node_modules/depd/Readme.md +280 -0
  76. package/example/node/node_modules/depd/index.js +522 -0
  77. package/example/node/node_modules/depd/lib/browser/index.js +77 -0
  78. package/example/node/node_modules/depd/lib/compat/callsite-tostring.js +103 -0
  79. package/example/node/node_modules/depd/lib/compat/event-listener-count.js +22 -0
  80. package/example/node/node_modules/depd/lib/compat/index.js +79 -0
  81. package/example/node/node_modules/depd/package.json +41 -0
  82. package/example/node/node_modules/destroy/LICENSE +22 -0
  83. package/example/node/node_modules/destroy/README.md +60 -0
  84. package/example/node/node_modules/destroy/index.js +75 -0
  85. package/example/node/node_modules/destroy/package.json +37 -0
  86. package/example/node/node_modules/ee-first/LICENSE +22 -0
  87. package/example/node/node_modules/ee-first/README.md +80 -0
  88. package/example/node/node_modules/ee-first/index.js +95 -0
  89. package/example/node/node_modules/ee-first/package.json +29 -0
  90. package/example/node/node_modules/encodeurl/HISTORY.md +14 -0
  91. package/example/node/node_modules/encodeurl/LICENSE +22 -0
  92. package/example/node/node_modules/encodeurl/README.md +128 -0
  93. package/example/node/node_modules/encodeurl/index.js +60 -0
  94. package/example/node/node_modules/encodeurl/package.json +40 -0
  95. package/example/node/node_modules/escape-html/LICENSE +24 -0
  96. package/example/node/node_modules/escape-html/Readme.md +43 -0
  97. package/example/node/node_modules/escape-html/index.js +78 -0
  98. package/example/node/node_modules/escape-html/package.json +24 -0
  99. package/example/node/node_modules/etag/HISTORY.md +83 -0
  100. package/example/node/node_modules/etag/LICENSE +22 -0
  101. package/example/node/node_modules/etag/README.md +159 -0
  102. package/example/node/node_modules/etag/index.js +131 -0
  103. package/example/node/node_modules/etag/package.json +47 -0
  104. package/example/node/node_modules/express/History.md +3510 -0
  105. package/example/node/node_modules/express/LICENSE +24 -0
  106. package/example/node/node_modules/express/Readme.md +158 -0
  107. package/example/node/node_modules/express/index.js +11 -0
  108. package/example/node/node_modules/express/lib/application.js +644 -0
  109. package/example/node/node_modules/express/lib/express.js +116 -0
  110. package/example/node/node_modules/express/lib/middleware/init.js +43 -0
  111. package/example/node/node_modules/express/lib/middleware/query.js +47 -0
  112. package/example/node/node_modules/express/lib/request.js +525 -0
  113. package/example/node/node_modules/express/lib/response.js +1147 -0
  114. package/example/node/node_modules/express/lib/router/index.js +668 -0
  115. package/example/node/node_modules/express/lib/router/layer.js +181 -0
  116. package/example/node/node_modules/express/lib/router/route.js +216 -0
  117. package/example/node/node_modules/express/lib/utils.js +302 -0
  118. package/example/node/node_modules/express/lib/view.js +182 -0
  119. package/example/node/node_modules/express/package.json +99 -0
  120. package/example/node/node_modules/finalhandler/HISTORY.md +187 -0
  121. package/example/node/node_modules/finalhandler/LICENSE +22 -0
  122. package/example/node/node_modules/finalhandler/README.md +148 -0
  123. package/example/node/node_modules/finalhandler/index.js +331 -0
  124. package/example/node/node_modules/finalhandler/package.json +45 -0
  125. package/example/node/node_modules/forwarded/HISTORY.md +21 -0
  126. package/example/node/node_modules/forwarded/LICENSE +22 -0
  127. package/example/node/node_modules/forwarded/README.md +57 -0
  128. package/example/node/node_modules/forwarded/index.js +90 -0
  129. package/example/node/node_modules/forwarded/package.json +45 -0
  130. package/example/node/node_modules/fresh/HISTORY.md +70 -0
  131. package/example/node/node_modules/fresh/LICENSE +23 -0
  132. package/example/node/node_modules/fresh/README.md +119 -0
  133. package/example/node/node_modules/fresh/index.js +137 -0
  134. package/example/node/node_modules/fresh/package.json +46 -0
  135. package/example/node/node_modules/http-errors/HISTORY.md +165 -0
  136. package/example/node/node_modules/http-errors/LICENSE +23 -0
  137. package/example/node/node_modules/http-errors/README.md +169 -0
  138. package/example/node/node_modules/http-errors/index.js +299 -0
  139. package/example/node/node_modules/http-errors/package.json +49 -0
  140. package/example/node/node_modules/iconv-lite/Changelog.md +162 -0
  141. package/example/node/node_modules/iconv-lite/LICENSE +21 -0
  142. package/example/node/node_modules/iconv-lite/README.md +156 -0
  143. package/example/node/node_modules/iconv-lite/encodings/dbcs-codec.js +555 -0
  144. package/example/node/node_modules/iconv-lite/encodings/dbcs-data.js +176 -0
  145. package/example/node/node_modules/iconv-lite/encodings/index.js +22 -0
  146. package/example/node/node_modules/iconv-lite/encodings/internal.js +188 -0
  147. package/example/node/node_modules/iconv-lite/encodings/sbcs-codec.js +72 -0
  148. package/example/node/node_modules/iconv-lite/encodings/sbcs-data-generated.js +451 -0
  149. package/example/node/node_modules/iconv-lite/encodings/sbcs-data.js +174 -0
  150. package/example/node/node_modules/iconv-lite/encodings/tables/big5-added.json +122 -0
  151. package/example/node/node_modules/iconv-lite/encodings/tables/cp936.json +264 -0
  152. package/example/node/node_modules/iconv-lite/encodings/tables/cp949.json +273 -0
  153. package/example/node/node_modules/iconv-lite/encodings/tables/cp950.json +177 -0
  154. package/example/node/node_modules/iconv-lite/encodings/tables/eucjp.json +182 -0
  155. package/example/node/node_modules/iconv-lite/encodings/tables/gb18030-ranges.json +1 -0
  156. package/example/node/node_modules/iconv-lite/encodings/tables/gbk-added.json +55 -0
  157. package/example/node/node_modules/iconv-lite/encodings/tables/shiftjis.json +125 -0
  158. package/example/node/node_modules/iconv-lite/encodings/utf16.js +177 -0
  159. package/example/node/node_modules/iconv-lite/encodings/utf7.js +290 -0
  160. package/example/node/node_modules/iconv-lite/lib/bom-handling.js +52 -0
  161. package/example/node/node_modules/iconv-lite/lib/extend-node.js +217 -0
  162. package/example/node/node_modules/iconv-lite/lib/index.d.ts +24 -0
  163. package/example/node/node_modules/iconv-lite/lib/index.js +153 -0
  164. package/example/node/node_modules/iconv-lite/lib/streams.js +121 -0
  165. package/example/node/node_modules/iconv-lite/package.json +46 -0
  166. package/example/node/node_modules/inherits/LICENSE +16 -0
  167. package/example/node/node_modules/inherits/README.md +42 -0
  168. package/example/node/node_modules/inherits/inherits.js +9 -0
  169. package/example/node/node_modules/inherits/inherits_browser.js +27 -0
  170. package/example/node/node_modules/inherits/package.json +29 -0
  171. package/example/node/node_modules/ipaddr.js/LICENSE +19 -0
  172. package/example/node/node_modules/ipaddr.js/README.md +233 -0
  173. package/example/node/node_modules/ipaddr.js/ipaddr.min.js +1 -0
  174. package/example/node/node_modules/ipaddr.js/lib/ipaddr.js +673 -0
  175. package/example/node/node_modules/ipaddr.js/lib/ipaddr.js.d.ts +68 -0
  176. package/example/node/node_modules/ipaddr.js/package.json +35 -0
  177. package/example/node/node_modules/media-typer/HISTORY.md +22 -0
  178. package/example/node/node_modules/media-typer/LICENSE +22 -0
  179. package/example/node/node_modules/media-typer/README.md +81 -0
  180. package/example/node/node_modules/media-typer/index.js +270 -0
  181. package/example/node/node_modules/media-typer/package.json +26 -0
  182. package/example/node/node_modules/merge-descriptors/HISTORY.md +21 -0
  183. package/example/node/node_modules/merge-descriptors/LICENSE +23 -0
  184. package/example/node/node_modules/merge-descriptors/README.md +48 -0
  185. package/example/node/node_modules/merge-descriptors/index.js +60 -0
  186. package/example/node/node_modules/merge-descriptors/package.json +32 -0
  187. package/example/node/node_modules/methods/HISTORY.md +29 -0
  188. package/example/node/node_modules/methods/LICENSE +24 -0
  189. package/example/node/node_modules/methods/README.md +51 -0
  190. package/example/node/node_modules/methods/index.js +69 -0
  191. package/example/node/node_modules/methods/package.json +36 -0
  192. package/example/node/node_modules/mime/CHANGELOG.md +164 -0
  193. package/example/node/node_modules/mime/LICENSE +21 -0
  194. package/example/node/node_modules/mime/README.md +90 -0
  195. package/example/node/node_modules/mime/cli.js +8 -0
  196. package/example/node/node_modules/mime/mime.js +108 -0
  197. package/example/node/node_modules/mime/package.json +44 -0
  198. package/example/node/node_modules/mime/src/build.js +53 -0
  199. package/example/node/node_modules/mime/src/test.js +60 -0
  200. package/example/node/node_modules/mime/types.json +1 -0
  201. package/example/node/node_modules/mime-db/HISTORY.md +499 -0
  202. package/example/node/node_modules/mime-db/LICENSE +22 -0
  203. package/example/node/node_modules/mime-db/README.md +100 -0
  204. package/example/node/node_modules/mime-db/db.json +8471 -0
  205. package/example/node/node_modules/mime-db/index.js +11 -0
  206. package/example/node/node_modules/mime-db/package.json +59 -0
  207. package/example/node/node_modules/mime-types/HISTORY.md +388 -0
  208. package/example/node/node_modules/mime-types/LICENSE +23 -0
  209. package/example/node/node_modules/mime-types/README.md +113 -0
  210. package/example/node/node_modules/mime-types/index.js +188 -0
  211. package/example/node/node_modules/mime-types/package.json +44 -0
  212. package/example/node/node_modules/ms/index.js +152 -0
  213. package/example/node/node_modules/ms/license.md +21 -0
  214. package/example/node/node_modules/ms/package.json +37 -0
  215. package/example/node/node_modules/ms/readme.md +51 -0
  216. package/example/node/node_modules/negotiator/HISTORY.md +103 -0
  217. package/example/node/node_modules/negotiator/LICENSE +24 -0
  218. package/example/node/node_modules/negotiator/README.md +203 -0
  219. package/example/node/node_modules/negotiator/index.js +124 -0
  220. package/example/node/node_modules/negotiator/lib/charset.js +169 -0
  221. package/example/node/node_modules/negotiator/lib/encoding.js +184 -0
  222. package/example/node/node_modules/negotiator/lib/language.js +179 -0
  223. package/example/node/node_modules/negotiator/lib/mediaType.js +294 -0
  224. package/example/node/node_modules/negotiator/package.json +42 -0
  225. package/example/node/node_modules/on-finished/HISTORY.md +88 -0
  226. package/example/node/node_modules/on-finished/LICENSE +23 -0
  227. package/example/node/node_modules/on-finished/README.md +154 -0
  228. package/example/node/node_modules/on-finished/index.js +196 -0
  229. package/example/node/node_modules/on-finished/package.json +31 -0
  230. package/example/node/node_modules/parseurl/HISTORY.md +58 -0
  231. package/example/node/node_modules/parseurl/LICENSE +24 -0
  232. package/example/node/node_modules/parseurl/README.md +133 -0
  233. package/example/node/node_modules/parseurl/index.js +158 -0
  234. package/example/node/node_modules/parseurl/package.json +40 -0
  235. package/example/node/node_modules/path-to-regexp/History.md +36 -0
  236. package/example/node/node_modules/path-to-regexp/LICENSE +21 -0
  237. package/example/node/node_modules/path-to-regexp/Readme.md +35 -0
  238. package/example/node/node_modules/path-to-regexp/index.js +129 -0
  239. package/example/node/node_modules/path-to-regexp/package.json +30 -0
  240. package/example/node/node_modules/proxy-addr/HISTORY.md +161 -0
  241. package/example/node/node_modules/proxy-addr/LICENSE +22 -0
  242. package/example/node/node_modules/proxy-addr/README.md +139 -0
  243. package/example/node/node_modules/proxy-addr/index.js +327 -0
  244. package/example/node/node_modules/proxy-addr/package.json +47 -0
  245. package/example/node/node_modules/qs/.editorconfig +39 -0
  246. package/example/node/node_modules/qs/.eslintignore +2 -0
  247. package/example/node/node_modules/qs/.eslintrc +35 -0
  248. package/example/node/node_modules/qs/.github/FUNDING.yml +12 -0
  249. package/example/node/node_modules/qs/.nycrc +13 -0
  250. package/example/node/node_modules/qs/CHANGELOG.md +359 -0
  251. package/example/node/node_modules/qs/LICENSE.md +29 -0
  252. package/example/node/node_modules/qs/README.md +604 -0
  253. package/example/node/node_modules/qs/dist/qs.js +832 -0
  254. package/example/node/node_modules/qs/lib/formats.js +23 -0
  255. package/example/node/node_modules/qs/lib/index.js +11 -0
  256. package/example/node/node_modules/qs/lib/parse.js +257 -0
  257. package/example/node/node_modules/qs/lib/stringify.js +278 -0
  258. package/example/node/node_modules/qs/lib/utils.js +251 -0
  259. package/example/node/node_modules/qs/package.json +69 -0
  260. package/example/node/node_modules/qs/test/parse.js +772 -0
  261. package/example/node/node_modules/qs/test/stringify.js +793 -0
  262. package/example/node/node_modules/qs/test/utils.js +136 -0
  263. package/example/node/node_modules/range-parser/HISTORY.md +56 -0
  264. package/example/node/node_modules/range-parser/LICENSE +23 -0
  265. package/example/node/node_modules/range-parser/README.md +84 -0
  266. package/example/node/node_modules/range-parser/index.js +162 -0
  267. package/example/node/node_modules/range-parser/package.json +44 -0
  268. package/example/node/node_modules/raw-body/HISTORY.md +284 -0
  269. package/example/node/node_modules/raw-body/LICENSE +22 -0
  270. package/example/node/node_modules/raw-body/README.md +217 -0
  271. package/example/node/node_modules/raw-body/index.d.ts +87 -0
  272. package/example/node/node_modules/raw-body/index.js +286 -0
  273. package/example/node/node_modules/raw-body/package.json +48 -0
  274. package/example/node/node_modules/safe-buffer/LICENSE +21 -0
  275. package/example/node/node_modules/safe-buffer/README.md +584 -0
  276. package/example/node/node_modules/safe-buffer/index.d.ts +187 -0
  277. package/example/node/node_modules/safe-buffer/index.js +65 -0
  278. package/example/node/node_modules/safe-buffer/package.json +51 -0
  279. package/example/node/node_modules/safer-buffer/LICENSE +21 -0
  280. package/example/node/node_modules/safer-buffer/Porting-Buffer.md +268 -0
  281. package/example/node/node_modules/safer-buffer/Readme.md +156 -0
  282. package/example/node/node_modules/safer-buffer/dangerous.js +58 -0
  283. package/example/node/node_modules/safer-buffer/package.json +34 -0
  284. package/example/node/node_modules/safer-buffer/safer.js +77 -0
  285. package/example/node/node_modules/safer-buffer/tests.js +406 -0
  286. package/example/node/node_modules/send/HISTORY.md +506 -0
  287. package/example/node/node_modules/send/LICENSE +23 -0
  288. package/example/node/node_modules/send/README.md +327 -0
  289. package/example/node/node_modules/send/index.js +1133 -0
  290. package/example/node/node_modules/send/node_modules/.bin/mime +15 -0
  291. package/example/node/node_modules/send/node_modules/.bin/mime.cmd +7 -0
  292. package/example/node/node_modules/send/node_modules/ms/index.js +162 -0
  293. package/example/node/node_modules/send/node_modules/ms/license.md +21 -0
  294. package/example/node/node_modules/send/node_modules/ms/package.json +38 -0
  295. package/example/node/node_modules/send/node_modules/ms/readme.md +59 -0
  296. package/example/node/node_modules/send/package.json +61 -0
  297. package/example/node/node_modules/serve-static/HISTORY.md +459 -0
  298. package/example/node/node_modules/serve-static/LICENSE +25 -0
  299. package/example/node/node_modules/serve-static/README.md +257 -0
  300. package/example/node/node_modules/serve-static/index.js +210 -0
  301. package/example/node/node_modules/serve-static/package.json +42 -0
  302. package/example/node/node_modules/setprototypeof/LICENSE +13 -0
  303. package/example/node/node_modules/setprototypeof/README.md +31 -0
  304. package/example/node/node_modules/setprototypeof/index.d.ts +2 -0
  305. package/example/node/node_modules/setprototypeof/index.js +17 -0
  306. package/example/node/node_modules/setprototypeof/package.json +38 -0
  307. package/example/node/node_modules/setprototypeof/test/index.js +24 -0
  308. package/example/node/node_modules/statuses/HISTORY.md +65 -0
  309. package/example/node/node_modules/statuses/LICENSE +23 -0
  310. package/example/node/node_modules/statuses/README.md +127 -0
  311. package/example/node/node_modules/statuses/codes.json +66 -0
  312. package/example/node/node_modules/statuses/index.js +113 -0
  313. package/example/node/node_modules/statuses/package.json +48 -0
  314. package/example/node/node_modules/toidentifier/HISTORY.md +9 -0
  315. package/example/node/node_modules/toidentifier/LICENSE +21 -0
  316. package/example/node/node_modules/toidentifier/README.md +61 -0
  317. package/example/node/node_modules/toidentifier/index.js +32 -0
  318. package/example/node/node_modules/toidentifier/package.json +38 -0
  319. package/example/node/node_modules/type-is/HISTORY.md +259 -0
  320. package/example/node/node_modules/type-is/LICENSE +23 -0
  321. package/example/node/node_modules/type-is/README.md +170 -0
  322. package/example/node/node_modules/type-is/index.js +266 -0
  323. package/example/node/node_modules/type-is/package.json +45 -0
  324. package/example/node/node_modules/unpipe/HISTORY.md +4 -0
  325. package/example/node/node_modules/unpipe/LICENSE +22 -0
  326. package/example/node/node_modules/unpipe/README.md +43 -0
  327. package/example/node/node_modules/unpipe/index.js +69 -0
  328. package/example/node/node_modules/unpipe/package.json +27 -0
  329. package/example/node/node_modules/utils-merge/LICENSE +20 -0
  330. package/example/node/node_modules/utils-merge/README.md +34 -0
  331. package/example/node/node_modules/utils-merge/index.js +23 -0
  332. package/example/node/node_modules/utils-merge/package.json +40 -0
  333. package/example/node/node_modules/vary/HISTORY.md +39 -0
  334. package/example/node/node_modules/vary/LICENSE +22 -0
  335. package/example/node/node_modules/vary/README.md +101 -0
  336. package/example/node/node_modules/vary/index.js +149 -0
  337. package/example/node/node_modules/vary/package.json +43 -0
  338. package/example/node/package.json +11 -0
  339. package/example/node/server.js +27 -15
  340. package/example/node/yarn.lock +352 -0
  341. package/package.json +29 -18
  342. package/src/index.js +16 -10
  343. package/src/lib/crawler/crawlers.js +1399 -11
  344. package/src/lib/crawler/exclusions.js +56 -9
  345. package/src/lib/crawler/headers.js +24 -15
  346. package/src/lib/crawler/provider.js +11 -13
  347. package/src/lib/crawler.js +123 -132
  348. package/test/lib/crawler.test.js +83 -24
  349. package/test/lib/database/crawlers.txt +3651 -0
  350. package/test/lib/database/devices.txt +165636 -0
  351. package/webpack.common.js +20 -20
  352. package/webpack.dev.js +7 -7
  353. package/webpack.prod.js +14 -15
@@ -0,0 +1,1147 @@
1
+ /*!
2
+ * express
3
+ * Copyright(c) 2009-2013 TJ Holowaychuk
4
+ * Copyright(c) 2014-2015 Douglas Christopher Wilson
5
+ * MIT Licensed
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ /**
11
+ * Module dependencies.
12
+ * @private
13
+ */
14
+
15
+ var Buffer = require('safe-buffer').Buffer
16
+ var contentDisposition = require('content-disposition');
17
+ var deprecate = require('depd')('express');
18
+ var encodeUrl = require('encodeurl');
19
+ var escapeHtml = require('escape-html');
20
+ var http = require('http');
21
+ var isAbsolute = require('./utils').isAbsolute;
22
+ var onFinished = require('on-finished');
23
+ var path = require('path');
24
+ var statuses = require('statuses')
25
+ var merge = require('utils-merge');
26
+ var sign = require('cookie-signature').sign;
27
+ var normalizeType = require('./utils').normalizeType;
28
+ var normalizeTypes = require('./utils').normalizeTypes;
29
+ var setCharset = require('./utils').setCharset;
30
+ var cookie = require('cookie');
31
+ var send = require('send');
32
+ var extname = path.extname;
33
+ var mime = send.mime;
34
+ var resolve = path.resolve;
35
+ var vary = require('vary');
36
+
37
+ /**
38
+ * Response prototype.
39
+ * @public
40
+ */
41
+
42
+ var res = Object.create(http.ServerResponse.prototype)
43
+
44
+ /**
45
+ * Module exports.
46
+ * @public
47
+ */
48
+
49
+ module.exports = res
50
+
51
+ /**
52
+ * Module variables.
53
+ * @private
54
+ */
55
+
56
+ var charsetRegExp = /;\s*charset\s*=/;
57
+
58
+ /**
59
+ * Set status `code`.
60
+ *
61
+ * @param {Number} code
62
+ * @return {ServerResponse}
63
+ * @public
64
+ */
65
+
66
+ res.status = function status(code) {
67
+ this.statusCode = code;
68
+ return this;
69
+ };
70
+
71
+ /**
72
+ * Set Link header field with the given `links`.
73
+ *
74
+ * Examples:
75
+ *
76
+ * res.links({
77
+ * next: 'http://api.example.com/users?page=2',
78
+ * last: 'http://api.example.com/users?page=5'
79
+ * });
80
+ *
81
+ * @param {Object} links
82
+ * @return {ServerResponse}
83
+ * @public
84
+ */
85
+
86
+ res.links = function(links){
87
+ var link = this.get('Link') || '';
88
+ if (link) link += ', ';
89
+ return this.set('Link', link + Object.keys(links).map(function(rel){
90
+ return '<' + links[rel] + '>; rel="' + rel + '"';
91
+ }).join(', '));
92
+ };
93
+
94
+ /**
95
+ * Send a response.
96
+ *
97
+ * Examples:
98
+ *
99
+ * res.send(Buffer.from('wahoo'));
100
+ * res.send({ some: 'json' });
101
+ * res.send('<p>some html</p>');
102
+ *
103
+ * @param {string|number|boolean|object|Buffer} body
104
+ * @public
105
+ */
106
+
107
+ res.send = function send(body) {
108
+ var chunk = body;
109
+ var encoding;
110
+ var req = this.req;
111
+ var type;
112
+
113
+ // settings
114
+ var app = this.app;
115
+
116
+ // allow status / body
117
+ if (arguments.length === 2) {
118
+ // res.send(body, status) backwards compat
119
+ if (typeof arguments[0] !== 'number' && typeof arguments[1] === 'number') {
120
+ deprecate('res.send(body, status): Use res.status(status).send(body) instead');
121
+ this.statusCode = arguments[1];
122
+ } else {
123
+ deprecate('res.send(status, body): Use res.status(status).send(body) instead');
124
+ this.statusCode = arguments[0];
125
+ chunk = arguments[1];
126
+ }
127
+ }
128
+
129
+ // disambiguate res.send(status) and res.send(status, num)
130
+ if (typeof chunk === 'number' && arguments.length === 1) {
131
+ // res.send(status) will set status message as text string
132
+ if (!this.get('Content-Type')) {
133
+ this.type('txt');
134
+ }
135
+
136
+ deprecate('res.send(status): Use res.sendStatus(status) instead');
137
+ this.statusCode = chunk;
138
+ chunk = statuses[chunk]
139
+ }
140
+
141
+ switch (typeof chunk) {
142
+ // string defaulting to html
143
+ case 'string':
144
+ if (!this.get('Content-Type')) {
145
+ this.type('html');
146
+ }
147
+ break;
148
+ case 'boolean':
149
+ case 'number':
150
+ case 'object':
151
+ if (chunk === null) {
152
+ chunk = '';
153
+ } else if (Buffer.isBuffer(chunk)) {
154
+ if (!this.get('Content-Type')) {
155
+ this.type('bin');
156
+ }
157
+ } else {
158
+ return this.json(chunk);
159
+ }
160
+ break;
161
+ }
162
+
163
+ // write strings in utf-8
164
+ if (typeof chunk === 'string') {
165
+ encoding = 'utf8';
166
+ type = this.get('Content-Type');
167
+
168
+ // reflect this in content-type
169
+ if (typeof type === 'string') {
170
+ this.set('Content-Type', setCharset(type, 'utf-8'));
171
+ }
172
+ }
173
+
174
+ // determine if ETag should be generated
175
+ var etagFn = app.get('etag fn')
176
+ var generateETag = !this.get('ETag') && typeof etagFn === 'function'
177
+
178
+ // populate Content-Length
179
+ var len
180
+ if (chunk !== undefined) {
181
+ if (Buffer.isBuffer(chunk)) {
182
+ // get length of Buffer
183
+ len = chunk.length
184
+ } else if (!generateETag && chunk.length < 1000) {
185
+ // just calculate length when no ETag + small chunk
186
+ len = Buffer.byteLength(chunk, encoding)
187
+ } else {
188
+ // convert chunk to Buffer and calculate
189
+ chunk = Buffer.from(chunk, encoding)
190
+ encoding = undefined;
191
+ len = chunk.length
192
+ }
193
+
194
+ this.set('Content-Length', len);
195
+ }
196
+
197
+ // populate ETag
198
+ var etag;
199
+ if (generateETag && len !== undefined) {
200
+ if ((etag = etagFn(chunk, encoding))) {
201
+ this.set('ETag', etag);
202
+ }
203
+ }
204
+
205
+ // freshness
206
+ if (req.fresh) this.statusCode = 304;
207
+
208
+ // strip irrelevant headers
209
+ if (204 === this.statusCode || 304 === this.statusCode) {
210
+ this.removeHeader('Content-Type');
211
+ this.removeHeader('Content-Length');
212
+ this.removeHeader('Transfer-Encoding');
213
+ chunk = '';
214
+ }
215
+
216
+ if (req.method === 'HEAD') {
217
+ // skip body for HEAD
218
+ this.end();
219
+ } else {
220
+ // respond
221
+ this.end(chunk, encoding);
222
+ }
223
+
224
+ return this;
225
+ };
226
+
227
+ /**
228
+ * Send JSON response.
229
+ *
230
+ * Examples:
231
+ *
232
+ * res.json(null);
233
+ * res.json({ user: 'tj' });
234
+ *
235
+ * @param {string|number|boolean|object} obj
236
+ * @public
237
+ */
238
+
239
+ res.json = function json(obj) {
240
+ var val = obj;
241
+
242
+ // allow status / body
243
+ if (arguments.length === 2) {
244
+ // res.json(body, status) backwards compat
245
+ if (typeof arguments[1] === 'number') {
246
+ deprecate('res.json(obj, status): Use res.status(status).json(obj) instead');
247
+ this.statusCode = arguments[1];
248
+ } else {
249
+ deprecate('res.json(status, obj): Use res.status(status).json(obj) instead');
250
+ this.statusCode = arguments[0];
251
+ val = arguments[1];
252
+ }
253
+ }
254
+
255
+ // settings
256
+ var app = this.app;
257
+ var escape = app.get('json escape')
258
+ var replacer = app.get('json replacer');
259
+ var spaces = app.get('json spaces');
260
+ var body = stringify(val, replacer, spaces, escape)
261
+
262
+ // content-type
263
+ if (!this.get('Content-Type')) {
264
+ this.set('Content-Type', 'application/json');
265
+ }
266
+
267
+ return this.send(body);
268
+ };
269
+
270
+ /**
271
+ * Send JSON response with JSONP callback support.
272
+ *
273
+ * Examples:
274
+ *
275
+ * res.jsonp(null);
276
+ * res.jsonp({ user: 'tj' });
277
+ *
278
+ * @param {string|number|boolean|object} obj
279
+ * @public
280
+ */
281
+
282
+ res.jsonp = function jsonp(obj) {
283
+ var val = obj;
284
+
285
+ // allow status / body
286
+ if (arguments.length === 2) {
287
+ // res.jsonp(body, status) backwards compat
288
+ if (typeof arguments[1] === 'number') {
289
+ deprecate('res.jsonp(obj, status): Use res.status(status).jsonp(obj) instead');
290
+ this.statusCode = arguments[1];
291
+ } else {
292
+ deprecate('res.jsonp(status, obj): Use res.status(status).jsonp(obj) instead');
293
+ this.statusCode = arguments[0];
294
+ val = arguments[1];
295
+ }
296
+ }
297
+
298
+ // settings
299
+ var app = this.app;
300
+ var escape = app.get('json escape')
301
+ var replacer = app.get('json replacer');
302
+ var spaces = app.get('json spaces');
303
+ var body = stringify(val, replacer, spaces, escape)
304
+ var callback = this.req.query[app.get('jsonp callback name')];
305
+
306
+ // content-type
307
+ if (!this.get('Content-Type')) {
308
+ this.set('X-Content-Type-Options', 'nosniff');
309
+ this.set('Content-Type', 'application/json');
310
+ }
311
+
312
+ // fixup callback
313
+ if (Array.isArray(callback)) {
314
+ callback = callback[0];
315
+ }
316
+
317
+ // jsonp
318
+ if (typeof callback === 'string' && callback.length !== 0) {
319
+ this.set('X-Content-Type-Options', 'nosniff');
320
+ this.set('Content-Type', 'text/javascript');
321
+
322
+ // restrict callback charset
323
+ callback = callback.replace(/[^\[\]\w$.]/g, '');
324
+
325
+ if (body === undefined) {
326
+ // empty argument
327
+ body = ''
328
+ } else if (typeof body === 'string') {
329
+ // replace chars not allowed in JavaScript that are in JSON
330
+ body = body
331
+ .replace(/\u2028/g, '\\u2028')
332
+ .replace(/\u2029/g, '\\u2029')
333
+ }
334
+
335
+ // the /**/ is a specific security mitigation for "Rosetta Flash JSONP abuse"
336
+ // the typeof check is just to reduce client error noise
337
+ body = '/**/ typeof ' + callback + ' === \'function\' && ' + callback + '(' + body + ');';
338
+ }
339
+
340
+ return this.send(body);
341
+ };
342
+
343
+ /**
344
+ * Send given HTTP status code.
345
+ *
346
+ * Sets the response status to `statusCode` and the body of the
347
+ * response to the standard description from node's http.STATUS_CODES
348
+ * or the statusCode number if no description.
349
+ *
350
+ * Examples:
351
+ *
352
+ * res.sendStatus(200);
353
+ *
354
+ * @param {number} statusCode
355
+ * @public
356
+ */
357
+
358
+ res.sendStatus = function sendStatus(statusCode) {
359
+ var body = statuses[statusCode] || String(statusCode)
360
+
361
+ this.statusCode = statusCode;
362
+ this.type('txt');
363
+
364
+ return this.send(body);
365
+ };
366
+
367
+ /**
368
+ * Transfer the file at the given `path`.
369
+ *
370
+ * Automatically sets the _Content-Type_ response header field.
371
+ * The callback `callback(err)` is invoked when the transfer is complete
372
+ * or when an error occurs. Be sure to check `res.headersSent`
373
+ * if you wish to attempt responding, as the header and some data
374
+ * may have already been transferred.
375
+ *
376
+ * Options:
377
+ *
378
+ * - `maxAge` defaulting to 0 (can be string converted by `ms`)
379
+ * - `root` root directory for relative filenames
380
+ * - `headers` object of headers to serve with file
381
+ * - `dotfiles` serve dotfiles, defaulting to false; can be `"allow"` to send them
382
+ *
383
+ * Other options are passed along to `send`.
384
+ *
385
+ * Examples:
386
+ *
387
+ * The following example illustrates how `res.sendFile()` may
388
+ * be used as an alternative for the `static()` middleware for
389
+ * dynamic situations. The code backing `res.sendFile()` is actually
390
+ * the same code, so HTTP cache support etc is identical.
391
+ *
392
+ * app.get('/user/:uid/photos/:file', function(req, res){
393
+ * var uid = req.params.uid
394
+ * , file = req.params.file;
395
+ *
396
+ * req.user.mayViewFilesFrom(uid, function(yes){
397
+ * if (yes) {
398
+ * res.sendFile('/uploads/' + uid + '/' + file);
399
+ * } else {
400
+ * res.send(403, 'Sorry! you cant see that.');
401
+ * }
402
+ * });
403
+ * });
404
+ *
405
+ * @public
406
+ */
407
+
408
+ res.sendFile = function sendFile(path, options, callback) {
409
+ var done = callback;
410
+ var req = this.req;
411
+ var res = this;
412
+ var next = req.next;
413
+ var opts = options || {};
414
+
415
+ if (!path) {
416
+ throw new TypeError('path argument is required to res.sendFile');
417
+ }
418
+
419
+ if (typeof path !== 'string') {
420
+ throw new TypeError('path must be a string to res.sendFile')
421
+ }
422
+
423
+ // support function as second arg
424
+ if (typeof options === 'function') {
425
+ done = options;
426
+ opts = {};
427
+ }
428
+
429
+ if (!opts.root && !isAbsolute(path)) {
430
+ throw new TypeError('path must be absolute or specify root to res.sendFile');
431
+ }
432
+
433
+ // create file stream
434
+ var pathname = encodeURI(path);
435
+ var file = send(req, pathname, opts);
436
+
437
+ // transfer
438
+ sendfile(res, file, opts, function (err) {
439
+ if (done) return done(err);
440
+ if (err && err.code === 'EISDIR') return next();
441
+
442
+ // next() all but write errors
443
+ if (err && err.code !== 'ECONNABORTED' && err.syscall !== 'write') {
444
+ next(err);
445
+ }
446
+ });
447
+ };
448
+
449
+ /**
450
+ * Transfer the file at the given `path`.
451
+ *
452
+ * Automatically sets the _Content-Type_ response header field.
453
+ * The callback `callback(err)` is invoked when the transfer is complete
454
+ * or when an error occurs. Be sure to check `res.headersSent`
455
+ * if you wish to attempt responding, as the header and some data
456
+ * may have already been transferred.
457
+ *
458
+ * Options:
459
+ *
460
+ * - `maxAge` defaulting to 0 (can be string converted by `ms`)
461
+ * - `root` root directory for relative filenames
462
+ * - `headers` object of headers to serve with file
463
+ * - `dotfiles` serve dotfiles, defaulting to false; can be `"allow"` to send them
464
+ *
465
+ * Other options are passed along to `send`.
466
+ *
467
+ * Examples:
468
+ *
469
+ * The following example illustrates how `res.sendfile()` may
470
+ * be used as an alternative for the `static()` middleware for
471
+ * dynamic situations. The code backing `res.sendfile()` is actually
472
+ * the same code, so HTTP cache support etc is identical.
473
+ *
474
+ * app.get('/user/:uid/photos/:file', function(req, res){
475
+ * var uid = req.params.uid
476
+ * , file = req.params.file;
477
+ *
478
+ * req.user.mayViewFilesFrom(uid, function(yes){
479
+ * if (yes) {
480
+ * res.sendfile('/uploads/' + uid + '/' + file);
481
+ * } else {
482
+ * res.send(403, 'Sorry! you cant see that.');
483
+ * }
484
+ * });
485
+ * });
486
+ *
487
+ * @public
488
+ */
489
+
490
+ res.sendfile = function (path, options, callback) {
491
+ var done = callback;
492
+ var req = this.req;
493
+ var res = this;
494
+ var next = req.next;
495
+ var opts = options || {};
496
+
497
+ // support function as second arg
498
+ if (typeof options === 'function') {
499
+ done = options;
500
+ opts = {};
501
+ }
502
+
503
+ // create file stream
504
+ var file = send(req, path, opts);
505
+
506
+ // transfer
507
+ sendfile(res, file, opts, function (err) {
508
+ if (done) return done(err);
509
+ if (err && err.code === 'EISDIR') return next();
510
+
511
+ // next() all but write errors
512
+ if (err && err.code !== 'ECONNABORTED' && err.syscall !== 'write') {
513
+ next(err);
514
+ }
515
+ });
516
+ };
517
+
518
+ res.sendfile = deprecate.function(res.sendfile,
519
+ 'res.sendfile: Use res.sendFile instead');
520
+
521
+ /**
522
+ * Transfer the file at the given `path` as an attachment.
523
+ *
524
+ * Optionally providing an alternate attachment `filename`,
525
+ * and optional callback `callback(err)`. The callback is invoked
526
+ * when the data transfer is complete, or when an error has
527
+ * ocurred. Be sure to check `res.headersSent` if you plan to respond.
528
+ *
529
+ * Optionally providing an `options` object to use with `res.sendFile()`.
530
+ * This function will set the `Content-Disposition` header, overriding
531
+ * any `Content-Disposition` header passed as header options in order
532
+ * to set the attachment and filename.
533
+ *
534
+ * This method uses `res.sendFile()`.
535
+ *
536
+ * @public
537
+ */
538
+
539
+ res.download = function download (path, filename, options, callback) {
540
+ var done = callback;
541
+ var name = filename;
542
+ var opts = options || null
543
+
544
+ // support function as second or third arg
545
+ if (typeof filename === 'function') {
546
+ done = filename;
547
+ name = null;
548
+ opts = null
549
+ } else if (typeof options === 'function') {
550
+ done = options
551
+ opts = null
552
+ }
553
+
554
+ // set Content-Disposition when file is sent
555
+ var headers = {
556
+ 'Content-Disposition': contentDisposition(name || path)
557
+ };
558
+
559
+ // merge user-provided headers
560
+ if (opts && opts.headers) {
561
+ var keys = Object.keys(opts.headers)
562
+ for (var i = 0; i < keys.length; i++) {
563
+ var key = keys[i]
564
+ if (key.toLowerCase() !== 'content-disposition') {
565
+ headers[key] = opts.headers[key]
566
+ }
567
+ }
568
+ }
569
+
570
+ // merge user-provided options
571
+ opts = Object.create(opts)
572
+ opts.headers = headers
573
+
574
+ // Resolve the full path for sendFile
575
+ var fullPath = resolve(path);
576
+
577
+ // send file
578
+ return this.sendFile(fullPath, opts, done)
579
+ };
580
+
581
+ /**
582
+ * Set _Content-Type_ response header with `type` through `mime.lookup()`
583
+ * when it does not contain "/", or set the Content-Type to `type` otherwise.
584
+ *
585
+ * Examples:
586
+ *
587
+ * res.type('.html');
588
+ * res.type('html');
589
+ * res.type('json');
590
+ * res.type('application/json');
591
+ * res.type('png');
592
+ *
593
+ * @param {String} type
594
+ * @return {ServerResponse} for chaining
595
+ * @public
596
+ */
597
+
598
+ res.contentType =
599
+ res.type = function contentType(type) {
600
+ var ct = type.indexOf('/') === -1
601
+ ? mime.lookup(type)
602
+ : type;
603
+
604
+ return this.set('Content-Type', ct);
605
+ };
606
+
607
+ /**
608
+ * Respond to the Acceptable formats using an `obj`
609
+ * of mime-type callbacks.
610
+ *
611
+ * This method uses `req.accepted`, an array of
612
+ * acceptable types ordered by their quality values.
613
+ * When "Accept" is not present the _first_ callback
614
+ * is invoked, otherwise the first match is used. When
615
+ * no match is performed the server responds with
616
+ * 406 "Not Acceptable".
617
+ *
618
+ * Content-Type is set for you, however if you choose
619
+ * you may alter this within the callback using `res.type()`
620
+ * or `res.set('Content-Type', ...)`.
621
+ *
622
+ * res.format({
623
+ * 'text/plain': function(){
624
+ * res.send('hey');
625
+ * },
626
+ *
627
+ * 'text/html': function(){
628
+ * res.send('<p>hey</p>');
629
+ * },
630
+ *
631
+ * 'application/json': function () {
632
+ * res.send({ message: 'hey' });
633
+ * }
634
+ * });
635
+ *
636
+ * In addition to canonicalized MIME types you may
637
+ * also use extnames mapped to these types:
638
+ *
639
+ * res.format({
640
+ * text: function(){
641
+ * res.send('hey');
642
+ * },
643
+ *
644
+ * html: function(){
645
+ * res.send('<p>hey</p>');
646
+ * },
647
+ *
648
+ * json: function(){
649
+ * res.send({ message: 'hey' });
650
+ * }
651
+ * });
652
+ *
653
+ * By default Express passes an `Error`
654
+ * with a `.status` of 406 to `next(err)`
655
+ * if a match is not made. If you provide
656
+ * a `.default` callback it will be invoked
657
+ * instead.
658
+ *
659
+ * @param {Object} obj
660
+ * @return {ServerResponse} for chaining
661
+ * @public
662
+ */
663
+
664
+ res.format = function(obj){
665
+ var req = this.req;
666
+ var next = req.next;
667
+
668
+ var fn = obj.default;
669
+ if (fn) delete obj.default;
670
+ var keys = Object.keys(obj);
671
+
672
+ var key = keys.length > 0
673
+ ? req.accepts(keys)
674
+ : false;
675
+
676
+ this.vary("Accept");
677
+
678
+ if (key) {
679
+ this.set('Content-Type', normalizeType(key).value);
680
+ obj[key](req, this, next);
681
+ } else if (fn) {
682
+ fn();
683
+ } else {
684
+ var err = new Error('Not Acceptable');
685
+ err.status = err.statusCode = 406;
686
+ err.types = normalizeTypes(keys).map(function(o){ return o.value });
687
+ next(err);
688
+ }
689
+
690
+ return this;
691
+ };
692
+
693
+ /**
694
+ * Set _Content-Disposition_ header to _attachment_ with optional `filename`.
695
+ *
696
+ * @param {String} filename
697
+ * @return {ServerResponse}
698
+ * @public
699
+ */
700
+
701
+ res.attachment = function attachment(filename) {
702
+ if (filename) {
703
+ this.type(extname(filename));
704
+ }
705
+
706
+ this.set('Content-Disposition', contentDisposition(filename));
707
+
708
+ return this;
709
+ };
710
+
711
+ /**
712
+ * Append additional header `field` with value `val`.
713
+ *
714
+ * Example:
715
+ *
716
+ * res.append('Link', ['<http://localhost/>', '<http://localhost:3000/>']);
717
+ * res.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly');
718
+ * res.append('Warning', '199 Miscellaneous warning');
719
+ *
720
+ * @param {String} field
721
+ * @param {String|Array} val
722
+ * @return {ServerResponse} for chaining
723
+ * @public
724
+ */
725
+
726
+ res.append = function append(field, val) {
727
+ var prev = this.get(field);
728
+ var value = val;
729
+
730
+ if (prev) {
731
+ // concat the new and prev vals
732
+ value = Array.isArray(prev) ? prev.concat(val)
733
+ : Array.isArray(val) ? [prev].concat(val)
734
+ : [prev, val]
735
+ }
736
+
737
+ return this.set(field, value);
738
+ };
739
+
740
+ /**
741
+ * Set header `field` to `val`, or pass
742
+ * an object of header fields.
743
+ *
744
+ * Examples:
745
+ *
746
+ * res.set('Foo', ['bar', 'baz']);
747
+ * res.set('Accept', 'application/json');
748
+ * res.set({ Accept: 'text/plain', 'X-API-Key': 'tobi' });
749
+ *
750
+ * Aliased as `res.header()`.
751
+ *
752
+ * @param {String|Object} field
753
+ * @param {String|Array} val
754
+ * @return {ServerResponse} for chaining
755
+ * @public
756
+ */
757
+
758
+ res.set =
759
+ res.header = function header(field, val) {
760
+ if (arguments.length === 2) {
761
+ var value = Array.isArray(val)
762
+ ? val.map(String)
763
+ : String(val);
764
+
765
+ // add charset to content-type
766
+ if (field.toLowerCase() === 'content-type') {
767
+ if (Array.isArray(value)) {
768
+ throw new TypeError('Content-Type cannot be set to an Array');
769
+ }
770
+ if (!charsetRegExp.test(value)) {
771
+ var charset = mime.charsets.lookup(value.split(';')[0]);
772
+ if (charset) value += '; charset=' + charset.toLowerCase();
773
+ }
774
+ }
775
+
776
+ this.setHeader(field, value);
777
+ } else {
778
+ for (var key in field) {
779
+ this.set(key, field[key]);
780
+ }
781
+ }
782
+ return this;
783
+ };
784
+
785
+ /**
786
+ * Get value for header `field`.
787
+ *
788
+ * @param {String} field
789
+ * @return {String}
790
+ * @public
791
+ */
792
+
793
+ res.get = function(field){
794
+ return this.getHeader(field);
795
+ };
796
+
797
+ /**
798
+ * Clear cookie `name`.
799
+ *
800
+ * @param {String} name
801
+ * @param {Object} [options]
802
+ * @return {ServerResponse} for chaining
803
+ * @public
804
+ */
805
+
806
+ res.clearCookie = function clearCookie(name, options) {
807
+ var opts = merge({ expires: new Date(1), path: '/' }, options);
808
+
809
+ return this.cookie(name, '', opts);
810
+ };
811
+
812
+ /**
813
+ * Set cookie `name` to `value`, with the given `options`.
814
+ *
815
+ * Options:
816
+ *
817
+ * - `maxAge` max-age in milliseconds, converted to `expires`
818
+ * - `signed` sign the cookie
819
+ * - `path` defaults to "/"
820
+ *
821
+ * Examples:
822
+ *
823
+ * // "Remember Me" for 15 minutes
824
+ * res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });
825
+ *
826
+ * // same as above
827
+ * res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })
828
+ *
829
+ * @param {String} name
830
+ * @param {String|Object} value
831
+ * @param {Object} [options]
832
+ * @return {ServerResponse} for chaining
833
+ * @public
834
+ */
835
+
836
+ res.cookie = function (name, value, options) {
837
+ var opts = merge({}, options);
838
+ var secret = this.req.secret;
839
+ var signed = opts.signed;
840
+
841
+ if (signed && !secret) {
842
+ throw new Error('cookieParser("secret") required for signed cookies');
843
+ }
844
+
845
+ var val = typeof value === 'object'
846
+ ? 'j:' + JSON.stringify(value)
847
+ : String(value);
848
+
849
+ if (signed) {
850
+ val = 's:' + sign(val, secret);
851
+ }
852
+
853
+ if ('maxAge' in opts) {
854
+ opts.expires = new Date(Date.now() + opts.maxAge);
855
+ opts.maxAge /= 1000;
856
+ }
857
+
858
+ if (opts.path == null) {
859
+ opts.path = '/';
860
+ }
861
+
862
+ this.append('Set-Cookie', cookie.serialize(name, String(val), opts));
863
+
864
+ return this;
865
+ };
866
+
867
+ /**
868
+ * Set the location header to `url`.
869
+ *
870
+ * The given `url` can also be "back", which redirects
871
+ * to the _Referrer_ or _Referer_ headers or "/".
872
+ *
873
+ * Examples:
874
+ *
875
+ * res.location('/foo/bar').;
876
+ * res.location('http://example.com');
877
+ * res.location('../login');
878
+ *
879
+ * @param {String} url
880
+ * @return {ServerResponse} for chaining
881
+ * @public
882
+ */
883
+
884
+ res.location = function location(url) {
885
+ var loc = url;
886
+
887
+ // "back" is an alias for the referrer
888
+ if (url === 'back') {
889
+ loc = this.req.get('Referrer') || '/';
890
+ }
891
+
892
+ // set location
893
+ return this.set('Location', encodeUrl(loc));
894
+ };
895
+
896
+ /**
897
+ * Redirect to the given `url` with optional response `status`
898
+ * defaulting to 302.
899
+ *
900
+ * The resulting `url` is determined by `res.location()`, so
901
+ * it will play nicely with mounted apps, relative paths,
902
+ * `"back"` etc.
903
+ *
904
+ * Examples:
905
+ *
906
+ * res.redirect('/foo/bar');
907
+ * res.redirect('http://example.com');
908
+ * res.redirect(301, 'http://example.com');
909
+ * res.redirect('../login'); // /blog/post/1 -> /blog/login
910
+ *
911
+ * @public
912
+ */
913
+
914
+ res.redirect = function redirect(url) {
915
+ var address = url;
916
+ var body;
917
+ var status = 302;
918
+
919
+ // allow status / url
920
+ if (arguments.length === 2) {
921
+ if (typeof arguments[0] === 'number') {
922
+ status = arguments[0];
923
+ address = arguments[1];
924
+ } else {
925
+ deprecate('res.redirect(url, status): Use res.redirect(status, url) instead');
926
+ status = arguments[1];
927
+ }
928
+ }
929
+
930
+ // Set location header
931
+ address = this.location(address).get('Location');
932
+
933
+ // Support text/{plain,html} by default
934
+ this.format({
935
+ text: function(){
936
+ body = statuses[status] + '. Redirecting to ' + address
937
+ },
938
+
939
+ html: function(){
940
+ var u = escapeHtml(address);
941
+ body = '<p>' + statuses[status] + '. Redirecting to <a href="' + u + '">' + u + '</a></p>'
942
+ },
943
+
944
+ default: function(){
945
+ body = '';
946
+ }
947
+ });
948
+
949
+ // Respond
950
+ this.statusCode = status;
951
+ this.set('Content-Length', Buffer.byteLength(body));
952
+
953
+ if (this.req.method === 'HEAD') {
954
+ this.end();
955
+ } else {
956
+ this.end(body);
957
+ }
958
+ };
959
+
960
+ /**
961
+ * Add `field` to Vary. If already present in the Vary set, then
962
+ * this call is simply ignored.
963
+ *
964
+ * @param {Array|String} field
965
+ * @return {ServerResponse} for chaining
966
+ * @public
967
+ */
968
+
969
+ res.vary = function(field){
970
+ // checks for back-compat
971
+ if (!field || (Array.isArray(field) && !field.length)) {
972
+ deprecate('res.vary(): Provide a field name');
973
+ return this;
974
+ }
975
+
976
+ vary(this, field);
977
+
978
+ return this;
979
+ };
980
+
981
+ /**
982
+ * Render `view` with the given `options` and optional callback `fn`.
983
+ * When a callback function is given a response will _not_ be made
984
+ * automatically, otherwise a response of _200_ and _text/html_ is given.
985
+ *
986
+ * Options:
987
+ *
988
+ * - `cache` boolean hinting to the engine it should cache
989
+ * - `filename` filename of the view being rendered
990
+ *
991
+ * @public
992
+ */
993
+
994
+ res.render = function render(view, options, callback) {
995
+ var app = this.req.app;
996
+ var done = callback;
997
+ var opts = options || {};
998
+ var req = this.req;
999
+ var self = this;
1000
+
1001
+ // support callback function as second arg
1002
+ if (typeof options === 'function') {
1003
+ done = options;
1004
+ opts = {};
1005
+ }
1006
+
1007
+ // merge res.locals
1008
+ opts._locals = self.locals;
1009
+
1010
+ // default callback to respond
1011
+ done = done || function (err, str) {
1012
+ if (err) return req.next(err);
1013
+ self.send(str);
1014
+ };
1015
+
1016
+ // render
1017
+ app.render(view, opts, done);
1018
+ };
1019
+
1020
+ // pipe the send file stream
1021
+ function sendfile(res, file, options, callback) {
1022
+ var done = false;
1023
+ var streaming;
1024
+
1025
+ // request aborted
1026
+ function onaborted() {
1027
+ if (done) return;
1028
+ done = true;
1029
+
1030
+ var err = new Error('Request aborted');
1031
+ err.code = 'ECONNABORTED';
1032
+ callback(err);
1033
+ }
1034
+
1035
+ // directory
1036
+ function ondirectory() {
1037
+ if (done) return;
1038
+ done = true;
1039
+
1040
+ var err = new Error('EISDIR, read');
1041
+ err.code = 'EISDIR';
1042
+ callback(err);
1043
+ }
1044
+
1045
+ // errors
1046
+ function onerror(err) {
1047
+ if (done) return;
1048
+ done = true;
1049
+ callback(err);
1050
+ }
1051
+
1052
+ // ended
1053
+ function onend() {
1054
+ if (done) return;
1055
+ done = true;
1056
+ callback();
1057
+ }
1058
+
1059
+ // file
1060
+ function onfile() {
1061
+ streaming = false;
1062
+ }
1063
+
1064
+ // finished
1065
+ function onfinish(err) {
1066
+ if (err && err.code === 'ECONNRESET') return onaborted();
1067
+ if (err) return onerror(err);
1068
+ if (done) return;
1069
+
1070
+ setImmediate(function () {
1071
+ if (streaming !== false && !done) {
1072
+ onaborted();
1073
+ return;
1074
+ }
1075
+
1076
+ if (done) return;
1077
+ done = true;
1078
+ callback();
1079
+ });
1080
+ }
1081
+
1082
+ // streaming
1083
+ function onstream() {
1084
+ streaming = true;
1085
+ }
1086
+
1087
+ file.on('directory', ondirectory);
1088
+ file.on('end', onend);
1089
+ file.on('error', onerror);
1090
+ file.on('file', onfile);
1091
+ file.on('stream', onstream);
1092
+ onFinished(res, onfinish);
1093
+
1094
+ if (options.headers) {
1095
+ // set headers on successful transfer
1096
+ file.on('headers', function headers(res) {
1097
+ var obj = options.headers;
1098
+ var keys = Object.keys(obj);
1099
+
1100
+ for (var i = 0; i < keys.length; i++) {
1101
+ var k = keys[i];
1102
+ res.setHeader(k, obj[k]);
1103
+ }
1104
+ });
1105
+ }
1106
+
1107
+ // pipe
1108
+ file.pipe(res);
1109
+ }
1110
+
1111
+ /**
1112
+ * Stringify JSON, like JSON.stringify, but v8 optimized, with the
1113
+ * ability to escape characters that can trigger HTML sniffing.
1114
+ *
1115
+ * @param {*} value
1116
+ * @param {function} replaces
1117
+ * @param {number} spaces
1118
+ * @param {boolean} escape
1119
+ * @returns {string}
1120
+ * @private
1121
+ */
1122
+
1123
+ function stringify (value, replacer, spaces, escape) {
1124
+ // v8 checks arguments.length for optimizing simple call
1125
+ // https://bugs.chromium.org/p/v8/issues/detail?id=4730
1126
+ var json = replacer || spaces
1127
+ ? JSON.stringify(value, replacer, spaces)
1128
+ : JSON.stringify(value);
1129
+
1130
+ if (escape && typeof json === 'string') {
1131
+ json = json.replace(/[<>&]/g, function (c) {
1132
+ switch (c.charCodeAt(0)) {
1133
+ case 0x3c:
1134
+ return '\\u003c'
1135
+ case 0x3e:
1136
+ return '\\u003e'
1137
+ case 0x26:
1138
+ return '\\u0026'
1139
+ /* istanbul ignore next: unreachable default */
1140
+ default:
1141
+ return c
1142
+ }
1143
+ })
1144
+ }
1145
+
1146
+ return json
1147
+ }