Compare commits

..

166 Commits

Author SHA1 Message Date
Feross Aboukhadijeh
d7613c3ac1 3.5.2 2020-11-05 11:17:57 -10:00
Feross Aboukhadijeh
953df40533
Merge pull request #47 from webtorrent/bitfield 2020-11-05 22:16:35 +01:00
Feross Aboukhadijeh
adf80f9e31 bitfield@4 2020-11-03 09:36:31 -10:00
Feross Aboukhadijeh
a19b83ad6d bump deps 2020-11-03 09:31:23 -10:00
Feross Aboukhadijeh
18c33fa5f7 package metadata 2020-07-16 21:49:31 -07:00
Feross Aboukhadijeh
eeeebdda22 3.5.1 2020-07-16 21:49:30 -07:00
Feross Aboukhadijeh
4f99851a9e deps 2020-07-16 21:49:16 -07:00
Feross Aboukhadijeh
c89df72e4e
Merge pull request #46 from webtorrent/greenkeeper/tape-5.0.0
Update tape to the latest version 🚀
2020-07-17 06:47:15 +02:00
greenkeeper[bot]
5bdc9df4f7
chore(package): update tape to version 5.0.0 2020-04-24 22:04:03 +00:00
Feross Aboukhadijeh
f2eb816fff 3.5.0 2019-09-07 09:24:05 -07:00
Feross Aboukhadijeh
8cfba16e12
Merge pull request #44 from bjornstar/nothing-after-cancel
Stop receiving data after cancel
2019-09-07 09:23:40 -07:00
Feross Aboukhadijeh
1013a093c7 3.4.1 2019-09-05 16:47:55 -07:00
Feross
cbd3f0d8b5
Update simple-sha1 to the latest version 🚀 (#45)
Update simple-sha1 to the latest version 🚀

Co-authored-by: null <23040076+greenkeeper[bot]@users.noreply.github.com>
2019-09-05 16:47:17 -07:00
greenkeeper[bot]
4a049f18cd
fix(package): update simple-sha1 to version 3.0.0 2019-09-05 23:06:14 +00:00
Feross Aboukhadijeh
d409e4bf2a 3.4.0 2019-07-20 11:43:33 -07:00
Feross Aboukhadijeh
96cbab00ce bitfield@3 2019-07-20 11:42:42 -07:00
Bjorn Stromberg
50ab830a75 Stop receiving data after cancel 2019-05-28 23:14:41 +09:00
Diego Rodríguez Baquero
60f328d8ba
Merge pull request #42 from webtorrent/greenkeeper/debug-4.0.0
Update debug to the latest version 🚀
2018-12-26 09:40:03 -05:00
greenkeeper[bot]
ea9fd78040 fix(package): update debug to version 4.0.0 2018-09-11 13:56:04 +00:00
Feross Aboukhadijeh
106acca7c8 3.3.0 2018-08-29 12:32:17 -07:00
Feross Aboukhadijeh
a9826a9612
Merge pull request #41 from jimmywarting/feature/modernize
modernize
2018-08-29 12:31:49 -07:00
Jimmy Wärting
4539a41dad modernize test files 2018-08-28 19:34:08 +02:00
Jimmy Wärting
6a0f5aecbe updated examples in readme 2018-08-28 13:27:03 +02:00
Jimmy Wärting
2034e9ed2c removed inherits dep 2018-08-28 11:42:05 +02:00
Jimmy Wärting
f84070f89a modernize index.js 2018-08-28 11:41:44 +02:00
Feross Aboukhadijeh
aa3f1459de remove safe-buffer 2018-07-26 21:26:04 -07:00
Feross Aboukhadijeh
3405e9a94e remove airtap 2018-07-26 21:20:20 -07:00
Diego Rodríguez Baquero
449dd19356
Merge pull request #39 from webtorrent/greenkeeper/bittorrent-protocol-3.0.0
Update bittorrent-protocol to the latest version 🚀
2018-07-26 20:10:53 -07:00
Diego Rodríguez Baquero
95abc05086
Merge branch 'master' into greenkeeper/bittorrent-protocol-3.0.0 2018-07-26 20:10:46 -07:00
Diego Rodríguez Baquero
7b1713ef96
Merge pull request #35 from webtorrent/greenkeeper/brfs-2.0.0
Update brfs to the latest version 🚀
2018-07-26 20:09:48 -07:00
Diego Rodríguez Baquero
1505eae11a
Merge pull request #40 from webtorrent/greenkeeper/airtap-0.1.0
chore(package): update airtap to version 0.1.0
2018-07-26 20:09:35 -07:00
greenkeeper[bot]
b45145bde5 chore(package): update bittorrent-protocol to version 3.0.0 2018-07-27 00:51:03 +00:00
greenkeeper[bot]
67b7fac40f chore(package): update airtap to version 0.1.0
Closes #36
2018-07-07 09:31:12 +00:00
greenkeeper[bot]
92fb4d380c chore(package): update brfs to version 2.0.0 2018-06-22 11:20:28 +00:00
Feross Aboukhadijeh
03050eca54 3.2.2 2018-06-09 16:19:42 -07:00
Feross Aboukhadijeh
6b8a93a9af npmignore 2018-06-09 16:16:01 -07:00
Feross Aboukhadijeh
d2f8239760
Merge pull request #34 from webtorrent/greenkeeper/airtap-0.0.7
chore(package): update airtap to version 0.0.7
2018-06-09 16:14:42 -07:00
greenkeeper[bot]
a2fa6e1212 chore(package): update airtap to version 0.0.7
Closes #32
2018-05-25 11:33:22 +00:00
Feross Aboukhadijeh
58b00eab05
Merge pull request #31 from webtorrent/greenkeeper/airtap-0.0.5
Update airtap to the latest version 🚀
2018-05-08 20:01:37 -07:00
greenkeeper[bot]
e19f8abcf6 chore(package): update airtap to version 0.0.5 2018-05-06 11:37:40 +00:00
Feross Aboukhadijeh
b584a2b93c 3.2.1 2018-04-12 23:50:58 -07:00
Feross Aboukhadijeh
04b2b55be4 zuul -> airtap 2018-04-12 23:46:02 -07:00
Feross Aboukhadijeh
e85020983e 3.2.0 2018-02-27 20:09:08 -08:00
Diego Rodríguez Baquero
084403d245
Merge pull request #29 from webtorrent/greenkeeper/bencode-2.0.0
Update bencode to the latest version 🚀
2018-02-26 15:02:06 -05:00
greenkeeper[bot]
7929a169e5 fix(package): update bencode to version 2.0.0 2018-02-26 18:18:51 +00:00
Feross Aboukhadijeh
ef43f5370f sauce: drop android 2018-02-20 15:24:46 -08:00
Feross Aboukhadijeh
bed0e361cc travis: node lts 2018-02-20 15:24:38 -08:00
Feross Aboukhadijeh
79ef8e4470 3.1.0 2018-02-20 15:23:40 -08:00
Diego Rodríguez Baquero
8bc4d72237
Merge pull request #28 from webtorrent/greenkeeper/bitfield-2.0.0
Update bitfield to the latest version 🚀
2018-02-20 09:43:46 -05:00
greenkeeper[bot]
635577950a fix(package): update bitfield to version 2.0.0 2018-02-20 05:52:47 +00:00
Feross Aboukhadijeh
2a39a8fe1c
remove greenkeeper badge 2018-01-29 19:09:40 +08:00
Diego Rodríguez Baquero
5aeaca0dd8 Merge pull request #25 from webtorrent/greenkeeper/initial
Update dependencies to enable Greenkeeper 🌴
2017-09-29 08:50:22 -05:00
Diego Rodríguez Baquero
9f78fc76ae Update README.md 2017-09-29 08:50:12 -05:00
greenkeeper[bot]
76362ff9ca docs(readme): add Greenkeeper badge 2017-09-29 05:23:28 +00:00
greenkeeper[bot]
ebfcb7df5f chore(package): update dependencies 2017-09-29 05:21:01 +00:00
Feross Aboukhadijeh
fb44d87d8a 3.0.11 2017-06-23 16:02:41 -07:00
Feross Aboukhadijeh
123f56ea7f bencode@1 2017-06-23 15:57:20 -07:00
Feross Aboukhadijeh
6467e7d9c7 3.0.10 2017-04-14 11:57:57 -07:00
Feross Aboukhadijeh
ca209b0345 package.json author 2017-04-14 10:42:42 -07:00
Feross Aboukhadijeh
5281ecf3a9 Merge pull request #22 from webtorrent/copyright
copyright
2017-04-14 10:32:01 -07:00
Feross Aboukhadijeh
b1b0beb92a Merge branch 'master' into copyright 2017-04-14 10:31:48 -07:00
Feross Aboukhadijeh
7c21d4d0ea Update README.md 2017-04-14 10:31:26 -07:00
Feross Aboukhadijeh
f80d9a5dde Merge pull request #21 from webtorrent/feross-patch-1
test pr (ignore)
2017-04-14 10:31:03 -07:00
Feross Aboukhadijeh
50997b24c4 copyright 2017-04-14 09:01:30 -07:00
Feross Aboukhadijeh
db07b7dd29 Update README.md 2017-04-14 08:55:08 -07:00
Feross Aboukhadijeh
9e0a3efabd test pr (ignore) 2017-04-13 22:51:04 -07:00
Feross Aboukhadijeh
4893baa94e feross -> webtorrent 2017-04-13 22:44:24 -07:00
Feross Aboukhadijeh
26f603e832 zuul: remove ie 2017-03-20 20:58:56 -07:00
Feross Aboukhadijeh
6b96881402 standard 2017-03-20 20:52:14 -07:00
Feross Aboukhadijeh
085e244ae8 3.0.9 2017-01-16 15:23:20 -08:00
Feross Aboukhadijeh
c3b453a5d8 Merge pull request #19 from feross/dep
bencode@0.11
2017-01-16 15:13:56 -08:00
Feross Aboukhadijeh
a86daa2460 bencode@0.11 2017-01-16 14:57:22 -08:00
Feross Aboukhadijeh
9ad818555d standard 2016-08-25 17:58:44 -07:00
Feross Aboukhadijeh
cd0a63689c 3.0.8 2016-05-30 01:43:12 -07:00
Feross Aboukhadijeh
9a1ddf367d add missing requires 2016-05-30 01:42:05 -07:00
Feross Aboukhadijeh
6a18461ba9 bencode@0.10 2016-05-30 01:38:56 -07:00
Feross Aboukhadijeh
e6aafdb332 Merge pull request #17 from feross/safe-buffer
Use safe-buffer
2016-05-30 01:38:07 -07:00
Feross Aboukhadijeh
9e9c187bf3 Use safe-buffer
Use the new Buffer APIs from Node v6 for added security. For example,
`Buffer.from()` will throw if passed a number, unlike `Buffer()` which
allocated UNINITIALIZED memory in that case.

Use the `safe-buffer` package for compatibility with previous versions
of Node.js, including v4.x, v0.12, and v0.10.

https://github.com/feross/safe-buffer
2016-05-30 00:56:47 -07:00
Feross Aboukhadijeh
37c73958eb Merge pull request #16 from feross/greenkeeper-standard-7.0.1
Update standard to version 7.0.1 🚀
2016-05-04 17:18:17 +02:00
greenkeeperio-bot
50f97ee821 chore(package): update standard to version 7.0.1
https://greenkeeper.io/
2016-05-04 16:54:16 +02:00
Feross Aboukhadijeh
6977f98a40 standard 2016-04-24 01:35:51 -07:00
Feross Aboukhadijeh
7f2a017982 3.0.7 2016-04-24 01:07:50 -07:00
Feross Aboukhadijeh
934517cfe6 standard 2016-04-24 01:03:02 -07:00
Feross Aboukhadijeh
9e5c1fbe94 3.0.6 2016-04-04 04:11:55 -07:00
Feross Aboukhadijeh
f872039875 Merge pull request #13 from feross/greenkeeper-bencode-0.9.0
Update bencode to version 0.9.0 🚀
2016-04-03 21:38:53 -07:00
greenkeeperio-bot
0d54b8a399 chore(package): update bencode to version 0.9.0
http://greenkeeper.io/
2016-04-02 18:24:38 -07:00
Feross Aboukhadijeh
297cf6e9a6 3.0.5 2016-03-23 18:27:42 -07:00
Feross Aboukhadijeh
84bc722156 Merge pull request #12 from feross/greenkeeper-bencode-0.8.0
Update bencode to version 0.8.0 🚀
2016-03-23 18:22:32 -07:00
greenkeeperio-bot
d20d1e10e8 chore(package): update bencode to version 0.8.0
http://greenkeeper.io/
2016-03-23 17:12:02 -07:00
Feross Aboukhadijeh
e247069bcf 3.0.4 2016-03-16 12:35:44 -07:00
Feross Aboukhadijeh
c91d132b6b use webtorrent-fixtures 2016-03-16 12:33:57 -07:00
Feross Aboukhadijeh
dfcbfdf1d2 zuul 2016-03-10 16:35:38 -08:00
Feross Aboukhadijeh
5fad79dd03 3.0.3 2016-02-27 22:57:52 -08:00
Feross Aboukhadijeh
b92c13afa8 zuul: remove flaky ios tests 2016-02-27 22:55:52 -08:00
Feross Aboukhadijeh
e0bcac622e Merge pull request #7 from feross/greenkeeper-parse-torrent-5.7.1
parse-torrent@5.7.1 breaks build 🚨
2016-02-14 01:23:48 -08:00
greenkeeperio-bot
0e05220ed9 chore(package): update parse-torrent to version 5.7.1
http://greenkeeper.io/
2016-02-14 00:48:03 -08:00
Feross Aboukhadijeh
cb95505f14 3.0.2 2016-02-09 22:20:07 -08:00
Feross Aboukhadijeh
b2824bb228 standard@6 2016-02-09 22:10:22 -08:00
Feross Aboukhadijeh
0734f4b4e0 add debug log 2016-02-09 22:09:48 -08:00
Feross Aboukhadijeh
9bf62ed135 standard 6 prep 2016-02-05 14:32:52 -08:00
Feross Aboukhadijeh
a04ea1dab5 badges 2016-02-05 14:32:49 -08:00
Feross Aboukhadijeh
afd5e5955e badge 2016-01-06 05:25:14 +01:00
Feross Aboukhadijeh
6fc24a9db2 3.0.1 2015-12-02 18:38:57 -08:00
Feross Aboukhadijeh
aabe79dde1 add missing zuul dependency 2015-12-02 18:33:10 -08:00
Feross Aboukhadijeh
62fbe8bd1b fix badge 2015-12-02 18:31:14 -08:00
Feross Aboukhadijeh
25598089a1 3.0.0 2015-12-02 18:29:32 -08:00
Feross Aboukhadijeh
5e87a38157 add sauce labs tests 2015-12-02 18:26:44 -08:00
Feross Aboukhadijeh
9e819ba3fe standard 2015-12-02 18:24:10 -08:00
Feross Aboukhadijeh
32f5c04b00 standard 2015-12-02 18:17:31 -08:00
Feross Aboukhadijeh
f77090a35c Changes for bittorrent-protocol@2 2015-12-02 18:17:15 -08:00
Feross Aboukhadijeh
3b97b75c15 bittorrent-protocol@2 2015-12-02 18:12:53 -08:00
Feross Aboukhadijeh
6b4d4a3ff1 parse-torrent@5 2015-12-02 18:12:36 -08:00
Feross Aboukhadijeh
6b2b79c875 2.7.4 2015-08-06 15:49:55 +02:00
Feross Aboukhadijeh
4a464c4bbb fix "npm docs" command 2015-08-06 15:49:35 +02:00
Feross Aboukhadijeh
093837f212 2.7.3 2015-05-04 17:27:29 -07:00
Feross Aboukhadijeh
9df4368701 tape@4 2015-05-04 17:26:59 -07:00
Feross Aboukhadijeh
c7890651e7 2.7.2 2015-02-28 17:07:36 -05:00
Feross Aboukhadijeh
772567c1d6 parse-torrent@4 2015-02-28 17:06:27 -05:00
Feross Aboukhadijeh
b0ec983a45 bencode@0.7 2015-02-28 17:05:42 -05:00
Feross Aboukhadijeh
fa6ef7a5ce 2.7.1 2015-01-22 15:11:11 -08:00
Feross Aboukhadijeh
ed8b7caff5 parse-torrent@3 2015-01-22 15:11:01 -08:00
Feross Aboukhadijeh
1e76d4d466 tape@3 2015-01-22 15:10:55 -08:00
Feross Aboukhadijeh
a49ecbd4d9 badges 2015-01-22 15:10:49 -08:00
Feross Aboukhadijeh
363ddd0acf 2.7.0 2015-01-04 21:54:53 -08:00
Feross Aboukhadijeh
633f2ad531 use simple-sha1 2015-01-04 21:54:47 -08:00
Feross Aboukhadijeh
463c5278c5 2.6.1 2014-12-17 22:17:15 -08:00
Feross Aboukhadijeh
cc6c738538 update comment for clarity 2014-12-17 22:17:08 -08:00
Feross Aboukhadijeh
720da46c44 2.6.0 2014-09-15 09:11:00 -07:00
Feross Aboukhadijeh
19c4543e44 use git-sha1 (for smaller bundle size) 2014-09-15 09:10:50 -07:00
Feross Aboukhadijeh
1e4851c9a3 2.5.1 2014-09-14 01:26:37 +01:00
Feross Aboukhadijeh
3d37d497bf update parse-torrent devdep 2014-09-14 01:26:31 +01:00
Feross Aboukhadijeh
2d15afd848 2.5.0 2014-08-17 03:09:05 -07:00
Feross Aboukhadijeh
9c7f5da432 ignore peers who report maliciously large metadata 2014-08-17 03:06:45 -07:00
Feross Aboukhadijeh
478cb13670 update deps 2014-08-17 03:06:31 -07:00
Feross Aboukhadijeh
c2ac02076b license 2014-08-10 05:14:17 -07:00
Feross Aboukhadijeh
2c65e06bbe 2.4.0 2014-07-02 15:23:53 -07:00
Feross Aboukhadijeh
30b5380ce3 remove rusha dep 2014-07-02 15:23:48 -07:00
Feross Aboukhadijeh
6c7adecf25 2.3.0 2014-06-11 17:56:30 -07:00
Feross Aboukhadijeh
b1e28a04a5 bncode -> bencode 2014-06-11 17:56:20 -07:00
Feross Aboukhadijeh
fe95752c37 ie10+ 2014-06-03 23:50:34 -07:00
Feross Aboukhadijeh
3ea372cfcf 2.2.1 2014-06-03 23:43:12 -07:00
Feross Aboukhadijeh
b55e0c306c support IE 2014-06-03 23:43:05 -07:00
Feross Aboukhadijeh
a33e454002 2.2.0 2014-06-03 23:11:17 -07:00
Feross Aboukhadijeh
7b4a888157 setMetadata handles info dict or full torrent dict 2014-06-03 23:11:04 -07:00
Feross Aboukhadijeh
e2b3a25670 readme typo 2014-06-03 21:30:09 -07:00
Feross Aboukhadijeh
69e25b5d2c remove pointless examples 2014-06-03 21:29:45 -07:00
Feross Aboukhadijeh
ec7c1e8a37 2.1.0 2014-06-03 21:29:06 -07:00
Feross Aboukhadijeh
e894a977f9 add setMetadata test 2014-06-03 21:27:33 -07:00
Feross Aboukhadijeh
b9741d834b improve readme 2014-06-03 21:17:43 -07:00
Feross Aboukhadijeh
47237ba54a expose setMetadata method 2014-06-03 21:17:25 -07:00
Feross Aboukhadijeh
9562a84c5a send reject message when we don't have piece 2014-06-03 21:17:16 -07:00
Feross Aboukhadijeh
d3d937fe27 2.0.2 2014-05-17 13:33:01 -07:00
Feross Aboukhadijeh
77b25ddeeb Merge pull request #5 from fisch0920/master
small bugfix for issue where peer may not have any extensions as advertised
2014-05-17 13:32:00 -07:00
fisch0920
6857b65d0b Merge remote-tracking branch 'upstream/master' 2014-05-15 06:31:58 -04:00
fisch0920
677e4522ea bugfix for issue where peer may not have any extensions as advertised 2014-05-15 06:31:42 -04:00
Feross Aboukhadijeh
1e19a567ff 2.0.1 2014-05-11 14:33:03 -07:00
Feross Aboukhadijeh
c998828d72 improve invalid metadata test 2014-05-11 14:32:49 -07:00
Feross Aboukhadijeh
82a02fd81a throw exception when metadata is bad 2014-05-11 14:23:19 -07:00
Feross Aboukhadijeh
1968e8ac10 2.0.0 2014-05-11 14:21:47 -07:00
fisch0920
5a3c0abe72 added missing ubuntu torrent file from last test case 2014-05-11 01:56:31 -04:00
fisch0920
1eef75b61e added test case confirming support of multi-block metadata 2014-05-11 01:53:46 -04:00
fisch0920
bc3d1ea668 fixed buggy metadata vs metadata.info 2014-05-09 07:11:14 -04:00
Feross Aboukhadijeh
1fde6fefbc 1.4.0 2014-05-07 12:10:13 -07:00
Feross Aboukhadijeh
2b60a6bde6 simplify metadata done check 2014-05-07 12:09:39 -07:00
fisch0920
4f002d7a76 fixed issue where ut_metadata thought it should have the whole torrent metadata whereas it actually only has the info dictionary part of the metadata 2014-05-07 02:00:17 -04:00
Feross Aboukhadijeh
57b57522bb style 2014-04-23 15:38:50 +02:00
10 changed files with 487 additions and 314 deletions

2
.npmignore Normal file
View File

@ -0,0 +1,2 @@
.travis.yml
test/

View File

@ -1,4 +1,3 @@
language: node_js language: node_js
node_js: node_js:
- "0.11" - lts/*
- "0.10"

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2013 Feross Aboukhadijeh Copyright (c) Feross Aboukhadijeh and WebTorrent, LLC
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in

View File

@ -1,37 +1,44 @@
# ut_metadata [![travis](https://img.shields.io/travis/feross/ut_metadata.svg)](https://travis-ci.org/feross/ut_metadata) [![npm](https://img.shields.io/npm/v/ut_metadata.svg)](https://npmjs.org/package/ut_metadata) [![gittip](https://img.shields.io/gittip/feross.svg)](https://www.gittip.com/feross/) # ut_metadata [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url]
[travis-image]: https://img.shields.io/travis/webtorrent/ut_metadata/master.svg
[travis-url]: https://travis-ci.org/webtorrent/ut_metadata
[npm-image]: https://img.shields.io/npm/v/ut_metadata.svg
[npm-url]: https://npmjs.org/package/ut_metadata
[downloads-image]: https://img.shields.io/npm/dm/ut_metadata.svg
[downloads-url]: https://npmjs.org/package/ut_metadata
[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg
[standard-url]: https://standardjs.com
### BitTorrent Extension for Peers to Send Metadata Files (BEP 9) ### BitTorrent Extension for Peers to Send Metadata Files (BEP 9)
[![browser support](https://ci.testling.com/feross/ut_metadata.png)](https://ci.testling.com/feross/ut_metadata) JavaScript implementation of the [Extension for Peers to Send Metadata Files (BEP 9)](http://www.bittorrent.org/beps/bep_0009.html). Use with [bittorrent-protocol](https://www.npmjs.com/package/bittorrent-protocol).
Node.js implementation of the [Extension for Peers to Send Metadata Files (BEP 9)](http://www.bittorrent.org/beps/bep_0009.html).
The purpose of this extension is to allow clients to join a swarm and complete a download without the need of downloading a .torrent file first. This extension instead allows clients to download the metadata from peers. It makes it possible to support magnet links, a link on a web page only containing enough information to join the swarm (the info hash). The purpose of this extension is to allow clients to join a swarm and complete a download without the need of downloading a .torrent file first. This extension instead allows clients to download the metadata from peers. It makes it possible to support magnet links, a link on a web page only containing enough information to join the swarm (the info hash).
Works in the browser with [browserify](http://browserify.org/)! This module is used by [WebTorrent](http://webtorrent.io). Works in the browser with [browserify](http://browserify.org/)! This module is used by [WebTorrent](http://webtorrent.io).
## install ### install
``` ```
npm install ut_metadata npm install ut_metadata
``` ```
## usage ### usage
This package should be used with [bittorrent-protocol](https://github.com/feross/bittorrent-protocol), which supports a plugin-like system for extending the protocol with additional functionality. This package should be used with [bittorrent-protocol](https://www.npmjs.com/package/bittorrent-protocol), which supports a plugin-like system for extending the protocol with additional functionality.
Say you're already using `bittorrent-protocol`. Your code might look something like this: Say you're already using `bittorrent-protocol`. Your code might look something like this:
```js ```js
var Protocol = require('bittorrent-protocol') const Protocol = require('bittorrent-protocol')
var net = require('net') const net = require('net')
net.createServer(function (socket) { net.createServer(socket => {
var wire = new Protocol() var wire = new Protocol()
socket.pipe(wire).pipe(socket) socket.pipe(wire).pipe(socket)
// handle handshake // handle handshake
wire.on('handshake', function (infoHash, peerId) { wire.on('handshake', (infoHash, peerId) => {
wire.handshake(new Buffer('my info hash'), new Buffer('my peer id')) wire.handshake(new Buffer('my info hash'), new Buffer('my peer id'))
}) })
@ -41,12 +48,12 @@ net.createServer(function (socket) {
To add support for BEP 9, simply modify your code like this: To add support for BEP 9, simply modify your code like this:
```js ```js
var Protocol = require('bittorrent-protocol') const Protocol = require('bittorrent-protocol')
var net = require('net') const net = require('net')
var ut_metadata = require('ut_metadata') const ut_metadata = require('ut_metadata')
net.createServer(function (socket) { net.createServer(socket => {
var wire = new Protocol() const wire = new Protocol()
socket.pipe(wire).pipe(socket) socket.pipe(wire).pipe(socket)
// initialize the extension // initialize the extension
@ -58,7 +65,7 @@ net.createServer(function (socket) {
wire.ut_metadata.fetch() wire.ut_metadata.fetch()
// 'metadata' event will fire when the metadata arrives and is verified to be correct! // 'metadata' event will fire when the metadata arrives and is verified to be correct!
wire.ut_metadata.on('metadata', function (metadata) { wire.ut_metadata.on('metadata', metadata => {
// got metadata! // got metadata!
// Note: the event will not fire if the peer does not support ut_metadata, if they // Note: the event will not fire if the peer does not support ut_metadata, if they
@ -68,43 +75,51 @@ net.createServer(function (socket) {
// optionally, listen to the 'warning' event if you want to know that metadata is // optionally, listen to the 'warning' event if you want to know that metadata is
// probably not going to arrive for one of the above reasons. // probably not going to arrive for one of the above reasons.
wire.ut_metadata.on('warning', function (err) { wire.ut_metadata.on('warning', err => {
console.log(err.message) console.log(err.message)
}) })
// handle handshake // handle handshake
wire.on('handshake', function (infoHash, peerId) { wire.on('handshake', (infoHash, peerId) => {
wire.handshake(new Buffer('my info hash'), new Buffer('my peer id')) wire.handshake(new Buffer('my info hash'), new Buffer('my peer id'))
}) })
}).listen(6881) }).listen(6881)
``` ```
## methods ### api
### fetch #### `ut_metadata([metadata])`
Initialize the extension. If you have the torrent metadata (Buffer), pass it into the
`ut_metadata` constructor so it's made available to the peer.
```js
const metadata = fs.readFileSync(__dirname + '/file.torrent')
wire.use(ut_metadata(metadata))
```
#### `ut_metadata.fetch()`
Ask the peer to send metadata. Ask the peer to send metadata.
```js #### `ut_metadata.cancel()`
wire.ut_metadata.fetch()
```
### cancel
Stop asking the peer to send metadata. Stop asking the peer to send metadata.
```js #### `ut_metadata.setMetadata(metadata)`
wire.ut_metadata.cancel()
```
### event: 'metadata' Set the metadata. If you didn't have the metadata at the time `ut_metadata` was
initialized, but you end up getting it from another peer (or somewhere else), you should
call `setMetadata` so the metadata will be available to the peer.
#### `ut_metadata.on('metadata', function (metadata) {})`
Fired when metadata is available and verified to be correct. Called with a single Fired when metadata is available and verified to be correct. Called with a single
parameter of type Buffer. parameter of type Buffer.
```js ```js
wire.ut_metadata.on('metadata', function (metadata) { wire.ut_metadata.on('metadata', metadata => {
console.log(Buffer.isBuffer(metadata)) // true console.log(Buffer.isBuffer(metadata)) // true
}) })
``` ```
@ -113,19 +128,19 @@ Note: the event will not fire if the peer does not support ut_metadata, if they
don't have metadata yet either, if they repeatedly send invalid data, or if they don't have metadata yet either, if they repeatedly send invalid data, or if they
simply don't respond. simply don't respond.
### event: 'warning' #### `ut_metadata.on('warning', function (err) {})`
Fired if: Fired if:
- the peer does not support ut_metadata - the peer does not support ut_metadata
- the peer doesn't have metadata yet - the peer doesn't have metadata yet
- the repeatedly sent invalid data - the peer repeatedly sent invalid data
```js ```js
wire.ut_metadata.on('warning', function (err) { wire.ut_metadata.on('warning', err => {
console.log(err.message) console.log(err.message)
}) })
``` ```
## license ### license
MIT. Copyright (c) [Feross Aboukhadijeh](http://feross.org). MIT. Copyright (c) [Feross Aboukhadijeh](https://feross.org) and [WebTorrent, LLC](https://webtorrent.io).

373
index.js
View File

@ -1,215 +1,244 @@
var BitField = require('bitfield') /*! ut_metadata. MIT License. WebTorrent LLC <https://webtorrent.io/opensource> */
var bncode = require('bncode') const { EventEmitter } = require('events')
var EventEmitter = require('events').EventEmitter const bencode = require('bencode')
var inherits = require('inherits') const BitField = require('bitfield').default
var Rusha = require('rusha-browserify') // Fast SHA1 (works in browser) const debug = require('debug')('ut_metadata')
const sha1 = require('simple-sha1')
var BITFIELD_GROW = 1000 const MAX_METADATA_SIZE = 1E7 // 10 MB
var PIECE_LENGTH = 16 * 1024 const BITFIELD_GROW = 1E3
const PIECE_LENGTH = 1 << 14 // 16 KiB
function sha1 (buf) { module.exports = metadata => {
return (new Rusha()).digestFromBuffer(buf) class utMetadata extends EventEmitter {
} constructor (wire) {
super()
module.exports = function (metadata) { this._wire = wire
inherits(ut_metadata, EventEmitter) this._fetching = false
this._metadataComplete = false
this._metadataSize = null
// how many reject messages to tolerate before quitting
this._remainingRejects = null
function ut_metadata (wire) { // The largest torrent file that I know of is ~1-2MB, which is ~100
EventEmitter.call(this) // pieces. Therefore, cap the bitfield to 10x that (1000 pieces) so a
// malicious peer can't make it grow to fill all memory.
this._bitfield = new BitField(0, { grow: BITFIELD_GROW })
this._wire = wire if (Buffer.isBuffer(metadata)) {
this.setMetadata(metadata)
this._metadataComplete = false }
this._metadataSize = null
this._remainingRejects = null // how many reject messages to tolerate before quitting
this._fetching = false
// The largest .torrent file that I know of is ~1-2MB, which is ~100 pieces.
// Therefore, cap the bitfield to 1,000 bits so a malicious peer can't make it grow
// to fill all memory.
this._bitfield = new BitField(0, { grow: BITFIELD_GROW })
if (Buffer.isBuffer(metadata)) {
this._gotMetadata(metadata)
}
}
ut_metadata.prototype.onHandshake = function (infoHash, peerId, extensions) {
this._infoHash = infoHash
}
ut_metadata.prototype.onExtendedHandshake = function (handshake) {
if (!handshake.m.ut_metadata) {
return this.emit('warning', new Error('Peer does not support ut_metadata'))
}
if (!handshake.metadata_size) {
return this.emit('warning', new Error('Peer does not have metadata'))
} }
this._metadataSize = handshake.metadata_size onHandshake (infoHash, peerId, extensions) {
this._numPieces = Math.ceil(this._metadataSize / PIECE_LENGTH) this._infoHash = infoHash
this._remainingRejects = this._numPieces * 2 }
onExtendedHandshake (handshake) {
if (!handshake.m || !handshake.m.ut_metadata) {
return this.emit('warning', new Error('Peer does not support ut_metadata'))
}
if (!handshake.metadata_size) {
return this.emit('warning', new Error('Peer does not have metadata'))
}
if (typeof handshake.metadata_size !== 'number' ||
MAX_METADATA_SIZE < handshake.metadata_size ||
handshake.metadata_size <= 0) {
return this.emit('warning', new Error('Peer gave invalid metadata size'))
}
this._metadataSize = handshake.metadata_size
this._numPieces = Math.ceil(this._metadataSize / PIECE_LENGTH)
this._remainingRejects = this._numPieces * 2
if (this._fetching) {
this._requestPieces() this._requestPieces()
} }
}
ut_metadata.prototype.onMessage = function (buf) { onMessage (buf) {
var dict, trailer let dict
try { let trailer
var str = buf.toString() try {
var trailerIndex = str.indexOf('ee') + 2 const str = buf.toString()
dict = bncode.decode(str.substring(0, trailerIndex)) const trailerIndex = str.indexOf('ee') + 2
trailer = buf.slice(trailerIndex) dict = bencode.decode(str.substring(0, trailerIndex))
} catch (err) { trailer = buf.slice(trailerIndex)
// drop invalid messages } catch (err) {
return // drop invalid messages
return
}
switch (dict.msg_type) {
case 0:
// ut_metadata request (from peer)
// example: { 'msg_type': 0, 'piece': 0 }
this._onRequest(dict.piece)
break
case 1:
// ut_metadata data (in response to our request)
// example: { 'msg_type': 1, 'piece': 0, 'total_size': 3425 }
this._onData(dict.piece, trailer, dict.total_size)
break
case 2:
// ut_metadata reject (peer doesn't have piece we requested)
// { 'msg_type': 2, 'piece': 0 }
this._onReject(dict.piece)
break
}
} }
switch (dict.msg_type) { /**
case 0: * Ask the peer to send metadata.
// ut_metadata request (from peer) * @public
// example: { 'msg_type': 0, 'piece': 0 } */
this._onRequest(dict.piece) fetch () {
break if (this._metadataComplete) {
case 1: return
// ut_metadata data (in response to our request) }
// example: { 'msg_type': 1, 'piece': 0, 'total_size': 3425 } this._fetching = true
this._onData(dict.piece, trailer, dict.total_size) if (this._metadataSize) {
break this._requestPieces()
case 2: }
// ut_metadata reject (peer doesn't have piece we requested)
// { 'msg_type': 2, 'piece': 0 }
this._onReject(dict.piece)
break
} }
}
// Expose high-level, friendly API (fetch/cancel) /**
ut_metadata.prototype.fetch = function () { * Stop asking the peer to send metadata.
if (this._metadataComplete) { * @public
return */
cancel () {
this._fetching = false
} }
this._fetching = true
if (this._metadataSize) { setMetadata (metadata) {
this._requestPieces() if (this._metadataComplete) return true
debug('set metadata')
// if full torrent dictionary was passed in, pull out just `info` key
try {
const info = bencode.decode(metadata).info
if (info) {
metadata = bencode.encode(info)
}
} catch (err) {}
// check hash
if (this._infoHash && this._infoHash !== sha1.sync(metadata)) {
return false
}
this.cancel()
this.metadata = metadata
this._metadataComplete = true
this._metadataSize = this.metadata.length
this._wire.extendedHandshake.metadata_size = this._metadataSize
this.emit('metadata', bencode.encode({
info: bencode.decode(this.metadata)
}))
return true
} }
}
ut_metadata.prototype.cancel = function () { _send (dict, trailer) {
this._fetching = false let buf = bencode.encode(dict)
} if (Buffer.isBuffer(trailer)) {
buf = Buffer.concat([buf, trailer])
ut_metadata.prototype._send = function (dict, trailer) { }
var buf = bncode.encode(dict) this._wire.extended('ut_metadata', buf)
if (Buffer.isBuffer(trailer)) {
buf = Buffer.concat([buf, trailer])
} }
this._wire.extended('ut_metadata', buf)
}
ut_metadata.prototype._request = function (piece) { _request (piece) {
this._send({ msg_type: 0, piece: piece }) this._send({ msg_type: 0, piece })
}
ut_metadata.prototype._data = function (piece, buf, totalSize) {
var msg = { msg_type: 1, piece: piece }
if (typeof totalSize === 'number') {
msg.total_size = totalSize
} }
this._send(msg, buf)
}
ut_metadata.prototype._reject = function (piece) { _data (piece, buf, totalSize) {
this._send({ msg_type: 2, piece: piece }) const msg = { msg_type: 1, piece }
} if (typeof totalSize === 'number') {
msg.total_size = totalSize
}
this._send(msg, buf)
}
ut_metadata.prototype._onRequest = function (piece) { _reject (piece) {
if (this._metadataComplete) { this._send({ msg_type: 2, piece })
var start = piece * PIECE_LENGTH }
var end = start + PIECE_LENGTH
_onRequest (piece) {
if (!this._metadataComplete) {
this._reject(piece)
return
}
const start = piece * PIECE_LENGTH
let end = start + PIECE_LENGTH
if (end > this._metadataSize) { if (end > this._metadataSize) {
end = this._metadataSize end = this._metadataSize
} }
var buf = this.metadata.slice(start, end) const buf = this.metadata.slice(start, end)
this._data(piece, buf, this._metadataSize) this._data(piece, buf, this._metadataSize)
} }
}
ut_metadata.prototype._onData = function (piece, buf, totalSize) { _onData (piece, buf, totalSize) {
if (buf.length > PIECE_LENGTH) { if (buf.length > PIECE_LENGTH || !this._fetching) {
return return
}
buf.copy(this.metadata, piece * PIECE_LENGTH)
this._bitfield.set(piece)
this._checkDone()
} }
buf.copy(this.metadata, piece * PIECE_LENGTH)
this._bitfield.set(piece)
this._checkDone()
}
ut_metadata.prototype._onReject = function (piece) { _onReject (piece) {
if (this._remainingRejects > 0 && this._fetching) { if (this._remainingRejects > 0 && this._fetching) {
// If we haven't been rejected too much, then try to request the piece again // If we haven't been rejected too much,
this._request(piece) // then try to request the piece again
this._remainingRejects -= 1 this._request(piece)
} else { this._remainingRejects -= 1
this.emit('warning', new Error('Peer sent "reject" too much')) } else {
} this.emit('warning', new Error('Peer sent "reject" too much'))
}
ut_metadata.prototype._requestPieces = function () {
this.metadata = new Buffer(this._metadataSize)
for (var piece = 0; piece < this._numPieces; piece++) {
this._request(piece)
}
}
ut_metadata.prototype._checkDone = function () {
var done = true
for (var piece = 0; piece < this._numPieces; piece++) {
if (!this._bitfield.get(piece)) {
done = false
break
} }
} }
if (!done) return
// check hash _requestPieces () {
var info if (!this._fetching) return
try { this.metadata = Buffer.alloc(this._metadataSize)
info = bncode.encode(bncode.decode(this.metadata).info) for (let piece = 0; piece < this._numPieces; piece++) {
} catch (err) { this._request(piece)
// if buffer fails to decode, then data was corrupt }
return this._failedMetadata()
}
if (sha1(info) === this._infoHash.toString('hex')) {
this._gotMetadata(this.metadata)
} else {
this._failedMetadata()
} }
} _checkDone () {
let done = true
for (let piece = 0; piece < this._numPieces; piece++) {
if (!this._bitfield.get(piece)) {
done = false
break
}
}
if (!done) return
ut_metadata.prototype._gotMetadata = function (_metadata) { // attempt to set metadata -- may fail sha1 check
this.cancel() const success = this.setMetadata(this.metadata)
this.metadata = _metadata
this._metadataComplete = true
this._metadataSize = this.metadata.length
this._wire.extendedHandshake.metadata_size = this._metadataSize
this.emit('metadata', this.metadata)
}
ut_metadata.prototype._failedMetadata = function () { if (!success) {
// reset bitfield & try again this._failedMetadata()
this._bitfield = new BitField(0, { grow: BITFIELD_GROW }) }
this._remainingRejects -= this._numPieces }
if (this._remainingRejects > 0) {
this._requestPieces() _failedMetadata () {
} else { // reset bitfield & try again
this.emit('warning', new Error('Peer sent invalid metadata')) this._bitfield = new BitField(0, { grow: BITFIELD_GROW })
this._remainingRejects -= this._numPieces
if (this._remainingRejects > 0) {
this._requestPieces()
} else {
this.emit('warning', new Error('Peer sent invalid metadata'))
}
} }
} }
return ut_metadata // Name of the bittorrent-protocol extension
utMetadata.prototype.name = 'ut_metadata'
return utMetadata
} }

View File

@ -1,57 +1,60 @@
{ {
"name": "ut_metadata", "name": "ut_metadata",
"description": "Extension for Peers to Send Metadata Files (BEP 9)", "description": "Extension for Peers to Send Metadata Files (BEP 9)",
"version": "1.3.1", "version": "3.5.2",
"author": { "author": {
"name": "Feross Aboukhadijeh", "name": "WebTorrent LLC",
"email": "feross@feross.org", "email": "feross@webtorrent.io",
"url": "http://feross.org/" "url": "https://webtorrent.io"
}, },
"bugs": { "bugs": {
"url": "https://github.com/feross/ut_metadata/issues" "url": "https://github.com/webtorrent/ut_metadata/issues"
}, },
"dependencies": { "dependencies": {
"bitfield": "^1.0.1", "bencode": "^2.0.1",
"bncode": "^0.5.0", "bitfield": "^4.0.0",
"inherits": "^2.0.1", "debug": "^4.2.0",
"rusha-browserify": "^0.7.3" "simple-sha1": "^3.0.1"
}, },
"devDependencies": { "devDependencies": {
"bittorrent-protocol": "^1.0.0", "bittorrent-protocol": "^3.1.2",
"brfs": "^1.0.0", "brfs": "^2.0.2",
"parse-torrent": "^1.0.0", "standard": "*",
"tape": "^2.12.0" "tape": "^5.0.1",
"webtorrent-fixtures": "^1.7.3"
}, },
"homepage": "http://webtorrent.io",
"keywords": [ "keywords": [
"torrent",
"bittorrent",
"ut_metadata",
"bep_0009",
"bep 9",
"bep",
"9",
"Extension for Peers to Send Metadata Files", "Extension for Peers to Send Metadata Files",
"bep",
"bep 9",
"bep_0009",
"bittorrent",
"metadata", "metadata",
"p2p" "p2p",
"torrent",
"ut_metadata"
], ],
"license": "MIT", "license": "MIT",
"main": "index.js", "main": "index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/feross/ut_metadata.git" "url": "git://github.com/webtorrent/ut_metadata.git"
}, },
"scripts": { "scripts": {
"test": "tape test/*.js" "test": "standard && tape test/*.js"
}, },
"testling": { "funding": [
"files": "test/*.js", {
"browsers": [ "type": "github",
"ie/9..latest", "url": "https://github.com/sponsors/feross"
"chrome/25..latest", },
"firefox/20..latest", {
"safari/6..latest", "type": "patreon",
"opera/15.0..latest" "url": "https://www.patreon.com/feross"
] },
} {
"type": "consulting",
"url": "https://feross.org/support"
}
]
} }

View File

@ -1,16 +1,14 @@
var fs = require('fs') const { leavesMetadata } = require('webtorrent-fixtures')
var Protocol = require('bittorrent-protocol') const bencode = require('bencode')
var ut_metadata = require('../') const Protocol = require('bittorrent-protocol')
var test = require('tape') const test = require('tape')
const utMetadata = require('../')
// Used in multiple tests test('wire.use(utMetadata())', t => {
var metadata = fs.readFileSync(__dirname + '/torrents/leaves-magnet.torrent') const wire = new Protocol()
test('wire.use(ut_metadata())', function (t) {
var wire = new Protocol()
wire.pipe(wire) wire.pipe(wire)
wire.use(ut_metadata()) wire.use(utMetadata())
t.ok(wire.ut_metadata) t.ok(wire.ut_metadata)
t.ok(wire.ut_metadata.fetch) t.ok(wire.ut_metadata.fetch)
@ -19,15 +17,18 @@ test('wire.use(ut_metadata())', function (t) {
t.end() t.end()
}) })
test('wire.use(ut_metadata(metadata))', function (t) { test('wire.use(utMetadata(metadata))', t => {
var wire = new Protocol() const wire = new Protocol()
wire.pipe(wire) wire.pipe(wire)
wire.use(ut_metadata(metadata)) wire.use(utMetadata(leavesMetadata.torrent))
t.ok(wire.ut_metadata) t.ok(wire.ut_metadata)
t.ok(wire.ut_metadata.fetch) t.ok(wire.ut_metadata.fetch)
t.ok(wire.ut_metadata.cancel) t.ok(wire.ut_metadata.cancel)
t.equal(wire.ut_metadata.metadata, metadata) t.equal(
wire.ut_metadata.metadata.toString('hex'),
bencode.encode(bencode.decode(leavesMetadata.torrent).info).toString('hex')
)
t.end() t.end()
}) })

View File

@ -1,37 +1,39 @@
var fs = require('fs') const { leavesMetadata, sintel } = require('webtorrent-fixtures')
var parseTorrent = require('parse-torrent') const bencode = require('bencode')
var Protocol = require('bittorrent-protocol') const Protocol = require('bittorrent-protocol')
var ut_metadata = require('../') const test = require('tape')
var test = require('tape') const utMetadata = require('../')
// Used in multiple tests const id1 = Buffer.from('01234567890123456789')
var metadata = fs.readFileSync(__dirname + '/torrents/leaves-magnet.torrent') const id2 = Buffer.from('12345678901234567890')
var parsedTorrent = parseTorrent(metadata)
var id1 = new Buffer('01234567890123456789')
var id2 = new Buffer('12345678901234567890')
test('fetch()', function (t) { test('fetch()', t => {
t.plan(3) t.plan(3)
var wire1 = new Protocol() const wire1 = new Protocol()
var wire2 = new Protocol() const wire2 = new Protocol()
wire1.pipe(wire2).pipe(wire1) wire1.pipe(wire2).pipe(wire1)
wire1.use(ut_metadata(metadata)) // wire1 already has metadata wire1.use(utMetadata(leavesMetadata.torrent)) // wire1 already has metadata
wire2.use(ut_metadata()) // wire2 does not wire2.use(utMetadata()) // wire2 does not
wire2.ut_metadata.fetch() wire2.ut_metadata.fetch()
wire2.ut_metadata.on('metadata', function (_metadata) { wire2.ut_metadata.on('metadata', _metadata => {
// got metadata! // got metadata!
t.deepEqual(_metadata, metadata) t.equal(
_metadata.toString('hex'),
bencode.encode({
info: bencode.decode(leavesMetadata.torrent).info
}).toString('hex')
)
}) })
wire2.on('handshake', function (infoHash, peerId, extensions) { wire2.on('handshake', (infoHash, peerId, extensions) => {
wire2.handshake(parsedTorrent.infoHash, id2) wire2.handshake(leavesMetadata.parsedTorrent.infoHash, id2)
}) })
wire2.on('extended', function (ext) { wire2.on('extended', ext => {
if (ext === 'handshake') { if (ext === 'handshake') {
t.pass('got extended handshake') t.pass('got extended handshake')
} else if (ext === 'ut_metadata') { } else if (ext === 'ut_metadata') {
@ -44,40 +46,40 @@ test('fetch()', function (t) {
} }
}) })
wire1.handshake(parsedTorrent.infoHash, id1) wire1.handshake(leavesMetadata.parsedTorrent.infoHash, id1)
}) })
test('fetch() from peer without metadata', function (t) { test('fetch() from peer without metadata', t => {
t.plan(2) t.plan(2)
var wire1 = new Protocol() const wire1 = new Protocol()
var wire2 = new Protocol() const wire2 = new Protocol()
wire1.pipe(wire2).pipe(wire1) wire1.pipe(wire2).pipe(wire1)
wire1.use(ut_metadata()) // neither wire has metadata wire1.use(utMetadata()) // neither wire has metadata
wire2.use(ut_metadata()) wire2.use(utMetadata())
wire2.ut_metadata.fetch() wire2.ut_metadata.fetch()
wire2.ut_metadata.on('metadata', function () { wire2.ut_metadata.on('metadata', () => {
t.fail('No "metadata" event should fire') t.fail('No "metadata" event should fire')
}) })
wire1.ut_metadata.onMessage = function () { wire1.ut_metadata.onMessage = () => {
t.fail('No messages should be sent to wire1') t.fail('No messages should be sent to wire1')
// No messages should be sent because wire1 never sent metadata_size in the // No messages should be sent because wire1 never sent metadata_size
// extended handshake, so he doesn't have metadata // in the extended handshake, so he doesn't have metadata
} }
wire2.ut_metadata.on('warning', function (err) { wire2.ut_metadata.on('warning', () => {
t.pass('got warning about peer missing metadata') t.pass('got warning about peer missing metadata')
}) })
wire2.on('handshake', function (infoHash, peerId, extensions) { wire2.on('handshake', (infoHash, peerId, extensions) => {
wire2.handshake(parsedTorrent.infoHash, id2) wire2.handshake(leavesMetadata.parsedTorrent.infoHash, id2)
}) })
wire2.on('extended', function (ext) { wire2.on('extended', ext => {
if (ext === 'handshake') { if (ext === 'handshake') {
t.pass('got extended handshake') t.pass('got extended handshake')
} else if (ext === 'ut_metadata') { } else if (ext === 'ut_metadata') {
@ -87,35 +89,163 @@ test('fetch() from peer without metadata', function (t) {
} }
}) })
wire1.handshake(parsedTorrent.infoHash, id1) wire1.handshake(leavesMetadata.parsedTorrent.infoHash, id1)
}) })
test('discard invalid metadata', function (t) { test('fetch when peer gets metadata later (setMetadata)', t => {
t.plan(1) t.plan(3)
const wire1 = new Protocol()
const wire2 = new Protocol()
var wire1 = new Protocol()
var wire2 = new Protocol()
wire1.pipe(wire2).pipe(wire1) wire1.pipe(wire2).pipe(wire1)
var invalidMetadata = metadata.slice(0) wire1.use(utMetadata()) // wire1 starts without metadata
invalidMetadata[0] = 99 // mess up the first byte of the metadata
wire1.use(ut_metadata(invalidMetadata)) process.nextTick(() => {
wire2.use(ut_metadata()) // wire1 gets metadata later
wire1.ut_metadata.setMetadata(leavesMetadata.torrent)
process.nextTick(() => {
// wire2 does not start with metadata,
// but connects to wire1 after it gets metadata
wire2.use(utMetadata())
wire2.ut_metadata.fetch()
wire2.ut_metadata.on('metadata', _metadata => {
// got metadata!
t.equal(
_metadata.toString('hex'),
bencode.encode({
info: bencode.decode(leavesMetadata.torrent).info
}).toString('hex')
)
})
wire2.on('handshake', (infoHash, peerId, extensions) => {
wire2.handshake(leavesMetadata.parsedTorrent.infoHash, id2)
})
wire2.on('extended', ext => {
if (ext === 'handshake') {
t.pass('got extended handshake')
} else if (ext === 'ut_metadata') {
t.pass('got extended ut_metadata message')
// this is emitted for consistency's sake, but it's ignored
// by the user since the ut_metadata package handles the
// complexities internally
} else {
t.fail('unexpected handshake type')
}
})
wire1.handshake(leavesMetadata.parsedTorrent.infoHash, id1)
})
})
})
test('fetch() large torrent', t => {
t.plan(4)
const wire1 = new Protocol()
const wire2 = new Protocol()
wire1.pipe(wire2).pipe(wire1)
wire1.use(utMetadata(sintel.torrent)) // wire1 already has metadata
wire2.use(utMetadata()) // wire2 does not
wire2.ut_metadata.fetch() wire2.ut_metadata.fetch()
wire2.ut_metadata.on('metadata', function () { wire2.ut_metadata.on('metadata', _metadata => {
// got metadata!
t.equal(
_metadata.toString('hex'),
bencode.encode({
info: bencode.decode(sintel.torrent).info
}).toString('hex')
)
})
wire2.on('handshake', (infoHash, peerId, extensions) => {
wire2.handshake(sintel.parsedTorrent.infoHash, id2)
})
wire2.on('extended', ext => {
if (ext === 'handshake') {
t.pass('got extended handshake')
} else if (ext === 'ut_metadata') {
// note: this should get called twice,
// once for each block of the sintel metadata
t.pass('got extended ut_metadata message')
// this is emitted for consistency's sake, but it's ignored
// by the user since the ut_metadata package handles the
// complexities internally
} else {
t.fail('unexpected handshake type')
}
})
wire1.handshake(sintel.parsedTorrent.infoHash, id1)
})
test('discard invalid metadata', t => {
t.plan(1)
const wire1 = new Protocol()
const wire2 = new Protocol()
wire1.pipe(wire2).pipe(wire1)
const invalidMetadata = leavesMetadata.torrent.slice(0)
invalidMetadata[55] = 65 // mess up a byte in the info block
wire1.use(utMetadata(invalidMetadata))
wire2.use(utMetadata())
wire2.ut_metadata.fetch()
wire2.ut_metadata.on('metadata', () => {
t.fail('No "metadata" event should fire') t.fail('No "metadata" event should fire')
}) })
wire2.ut_metadata.on('warning', function (err) { wire2.ut_metadata.on('warning', () => {
t.pass('got warning because peer sent reject too much') t.pass('got warning because peer sent reject too much')
}) })
wire2.on('handshake', function (infoHash, peerId, extensions) { wire2.on('handshake', (infoHash, peerId, extensions) => {
wire2.handshake(parsedTorrent.infoHash, id2) wire2.handshake(leavesMetadata.parsedTorrent.infoHash, id2)
}) })
wire1.handshake(parsedTorrent.infoHash, id1) wire1.handshake(leavesMetadata.parsedTorrent.infoHash, id1)
})
test('stop receiving data after cancel', t => {
t.plan(1)
const wire1 = new Protocol()
const wire2 = new Protocol()
wire1.pipe(wire2).pipe(wire1)
wire1.use(utMetadata(sintel.torrent))
wire2.use(utMetadata())
wire2.ut_metadata.once('metadata', () => {
t.fail('No "metadata" event should fire')
})
wire2.once('handshake', (infoHash, peerId, extensions) => {
wire2.handshake(sintel.parsedTorrent.infoHash, id2)
wire2.ut_metadata.fetch()
})
wire2.on('extended', ext => {
if (ext === 'ut_metadata') {
wire2.ut_metadata.cancel()
}
})
wire1.handshake(sintel.parsedTorrent.infoHash, id1)
process.nextTick(() => t.pass('no metadata received'))
}) })

View File

@ -1,13 +1,7 @@
{ {
"name": "test", "name": "test",
"version": "0.0.0", "version": "0.0.0",
"author": "Feross Aboukhadijeh <feross@feross.org> (http://feross.org/)",
"browserify": { "browserify": {
"transform": ["brfs"] "transform": ["brfs"]
},
"license": "MIT",
"main": "index.js",
"scripts": {
"test": "tape test/*.js"
} }
} }

Binary file not shown.