项目作者: ipfs-inactive

项目描述 :
[DEPRECATED] Use ipfs-message-port-server/client instead:
高级语言: JavaScript
项目地址: git://github.com/ipfs-inactive/ipfs-postmsg-proxy.git
创建时间: 2017-12-14T15:39:50Z
项目社区:https://github.com/ipfs-inactive/ipfs-postmsg-proxy

开源协议:MIT License

下载


⚠️ Deprecated ⚠️

This library has been deprecated and replaced with more flexible universal libraries for sharing API instance across message port:

This library will not be maintained.


ipfs-postmsg-proxy

Build Status dependencies Status deprecated

Proxy to an IPFS over window.postMessage

The proxy uses postmsg-rpc under the hood to create an object which looks like an IPFS instance on the web page. This is just an object with “stubs” (functions) that use window.postMessage to communicate with a real IPFS node running in the browser extension. postmsg-rpc allows us to create these stubs and expose methods on the IPFS node without having to deal with the complexities of window.postMessage.

  1. Web page Browser extension
  2. +---------------+-----------------+ +-------------------+----------------+
  3. | | | | | |
  4. | | | | | |
  5. | | | window.postMessage | | |
  6. | window.ipfs +-> call stubs +---------------------> exposed api +-> js-ipfs / |
  7. | <-+ (postmsg-rpc) <---------------------+ (postmsg-rpc) <-+ js-ipfs-api |
  8. | | | | | |
  9. | | | | | |
  10. | | | | | |
  11. +-------^-------+-----------------+ +-------------------+----------------+
  12. |
  13. +
  14. interface-ipfs-core

We’re using interface-ipfs-core to test our call stubs which are hooked up to a js-ipfs/js-ipfs-api on the other end. If the tests pass we know that the proxy is doing a good job of passing messages over the boundary.

When messages are passed using window.postMessage the data that is sent is cloned using the structured clone algorithm. It allows more things to be cloned than just JSON types but there are some things that cannot be cloned without some prior serialization to a format that can be cloned by the algorithm. For this reason, on both the web page and browser extension side we sometimes manually perform this serialization on arguments and return types.

In the web page, we serialize arguments we know cannot be handled by the structured clone algorithm before stubs are called and we deserialize them in the browser extension before exposed functions are called.

In the browser extension we serialize return values after exposed functions are called and deserialize them in the web page after stubs are called.

The prepost module provides these utility functions.

Install

  1. npm install ipfs-postmsg-proxy

Usage

In this example, IPFS is running in an iframe.

In iframe window where the js-ipfs node is running, create iframe.js:

  1. const IPFS = require('ipfs')
  2. const { createProxyServer, closeProxyServer } = require('ipfs-postmsg-proxy')
  3. const ipfs = new IPFS()
  4. // Create proxy server that talks to the parent window
  5. const server = createProxyServer(() => ipfs, {
  6. postMessage: window.parent.postMessage.bind(window.parent)
  7. })
  8. // Later, you might want to close the server:
  9. closeProxyServer(server)

Browserify/Webpack iframe.js to bundle.js.

Create iframe.html:

  1. <!doctype html>
  2. <script src="bundle.js"></script>

In the client window, add the iframe and create a client to talk to it:

  1. const { createProxyClient } = require('ipfs-postmsg-proxy')
  2. const iframe = document.createElement('iframe')
  3. iframe.src = 'iframe.html'
  4. document.body.appendChild(iframe)
  5. // Create proxy client that talks to the iframe
  6. window.ipfs = createProxyClient({
  7. postMessage: iframe.contentWindow.postMessage.bind(iframe.contentWindow)
  8. })
  9. // You can now interact with IPFS as usual, e.g.
  10. // ipfs.add(new Buffer('HELLO WORLD'), (err, res) => console.log(err, res))

API

createProxyServer(getIpfs, [options])

Create a proxy server to a running IPFS instance.

  • getIpfs - a function that returns the IPFS instance. Note this function will be called every time a function needs to be invoked and so shouldn’t create a new instance each time!
  • options.postMessage - function that posts a message (default window.postMessage)
  • options.targetOrigin - passed to postMessage. See postMessage docs for more info (default '*')
  • options.addListener - function that adds a listener (default window.addEventListener)
  • options.removeListener - function that removes a listener (default window.removeEventListener)
  • options.getMessageData - a function that extracts data from the event object passed to a message event handler (default (e) => e.data)
  • options.pre - an object or a function. If an object, it’s values are functions to call prior to invoking functions on the exposed IPFS node. The pre-functions are passed arguments as they would be passed to the exposed IPFS node and are expected to return an array of possibly altered arguments or a promise that resolves to the arguments array. The keys for this object identify the function name on the IPFS node that this function should be run before. e.g.

    1. createProxyServer(getIpfs, {
    2. pre: {
    3. 'files.add' (...args) {
    4. // Alter the args in some way...
    5. return args
    6. }
    7. }
    8. })

    If options.pre is a function it should create and return a pre-function (or null) for the passed function name. e.g.

    1. createProxyServer(getIpfs, {
    2. pre: (fnName) => (...args) => {
    3. // Alter the args in some way...
    4. return args
    5. }
    6. })

Returns an IPFS proxy server instance.

closeProxyServer(server)

Close the passed proxy server (removes all listeners for postMessage message events).

  • server - a proxy server created by createProxyServer

Returns a Promise that resolves once the server is fully closed.

createProxyClient([options])

Create a proxy client to the proxy server.

  • options.postMessage - function that posts a message (default window.postMessage)
  • options.targetOrigin - passed to postMessage. See postMessage docs for more info (default '*')
  • options.addListener - function that adds a listener (default window.addEventListener)
  • options.removeListener - function that removes a listener (default window.removeEventListener)
  • options.getMessageData - a function that extracts data from the event object passed to a message event handler (default (e) => e.data)

Returns an IPFS proxy client instance.

Current status

  1. $ npm run test:integration:node:js
  2. .bitswap.stat
  3. should get bitswap stats
  4. should get bitswap stats (promised)
  5. should not get bitswap stats when offline
  6. .bitswap.wantlist
  7. should get the wantlist
  8. should get the wantlist by peer ID for a diffreent node
  9. should not get the wantlist when offline
  10. .block.put
  11. should put a buffer, using defaults
  12. should put a buffer, using CID
  13. should put a buffer, using options
  14. should put a Block instance
  15. should error with array of blocks
  16. .block.get
  17. should get by CID object
  18. should get by CID in string
  19. should get an empty block
  20. .block.stat
  21. should stat by CID
  22. .bootstrap.add
  23. should return an error when called with an invalid arg
  24. should return a list containing the bootstrap peer when called with a valid arg (ip4)
  25. should return a list of bootstrap peers when called with the default option
  26. .bootstrap.list
  27. should return a list of peers
  28. .bootstrap.rm
  29. should return an error when called with an invalid arg
  30. should return an empty list because no peers removed when called without an arg or options
  31. should return a list containing the peer removed when called with a valid arg (ip4)
  32. should return a list of all peers removed when all option is passed
  33. .config.get
  34. should retrieve the whole config
  35. should retrieve the whole config (promised)
  36. should retrieve a value through a key
  37. should retrieve a value through a nested key
  38. should fail on non valid key
  39. should fail on non existent key
  40. .config.set
  41. should set a new key
  42. should set a new key (promised)
  43. should set an already existing key
  44. should set a JSON object
  45. should fail on non valid key
  46. should fail on non valid value
  47. .config.replace
  48. should replace the whole config
  49. should replace to empty config
  50. .dag.get
  51. should get a dag-pb node
  52. should get a dag-cbor node
  53. should get a dag-pb node with path
  54. should get a dag-pb node local value
  55. - should get a dag-pb node value one level deep
  56. - should get a dag-pb node value two levels deep
  57. should get a dag-cbor node with path
  58. should get a dag-cbor node local value
  59. - should get dag-cbor node value one level deep
  60. - should get dag-cbor node value two levels deep
  61. - should get dag-cbor value via dag-pb node
  62. should get dag-pb value via dag-cbor node
  63. should get by CID string
  64. should get by CID string + path
  65. .dag.put
  66. should put dag-pb with default hash func (sha2-256)
  67. should put dag-pb with custom hash func (sha3-512)
  68. should put dag-cbor with default hash func (sha2-256)
  69. should put dag-cbor with custom hash func (sha3-512)
  70. should return the cid
  71. should not fail when calling put without options
  72. should not fail when calling put without options (promised)
  73. should set defaults when calling put without options
  74. should set defaults when calling put without options (promised)
  75. should override hash algoritm default and resolve with it
  76. - should put by passing the cid instead of format and hashAlg
  77. .dag.tree
  78. should get tree with CID
  79. should get tree with CID and path
  80. should get tree with CID and path as String
  81. should get tree with CID recursive (accross different formats)
  82. should get tree with CID and path recursive
  83. .dht.get (TODO: DHT is not implemented in js-ipfs yet!)
  84. - should error when getting a non-existent key from the DHT
  85. - should get a value after it was put on another node
  86. .dht.put (TODO: DHT is not implemented in js-ipfs yet!)
  87. - should put a value on the DHT
  88. .dht.findpeer (TODO: DHT is not implemented in js-ipfs yet!)
  89. - should find other peers
  90. - should fail to find other peer if peer does not exist
  91. .dht.provide (TODO: DHT is not implemented in js-ipfs yet!)
  92. - should provide local CID
  93. - should not provide if block not found locally
  94. - should allow multiple CIDs to be passed
  95. - should provide a CIDv1
  96. - should error on non CID arg
  97. - should error on array containing non CID arg
  98. .dht.findprovs (TODO: DHT is not implemented in js-ipfs yet!)
  99. - should provide from one node and find it through another node
  100. - should take options to override timeout config
  101. .dht.query (TODO: DHT is not implemented in js-ipfs yet!)
  102. - should return the other node in the query
  103. .files.add
  104. should add a Buffer
  105. should add a Buffer (promised)
  106. should add a BIG Buffer
  107. should add a BIG Buffer with progress enabled
  108. should add a Buffer as tuple
  109. should not be able to add by path
  110. should add readable stream
  111. should add array of objects with readable stream content
  112. should add pull stream
  113. - should add pull stream (promised) (https://github.com/ipfs/js-ipfs/issues/1574)
  114. should add array of objects with pull stream content (promised)
  115. should add a nested directory as array of tupples
  116. should add a nested directory as array of tupples with progress
  117. should fail when passed invalid input
  118. should wrap content in a directory
  119. should add with only-hash=true (promised)
  120. .files.addReadableStream
  121. should add readable stream of valid files and dirs
  122. .files.addPullStream
  123. should add pull stream of valid files and dirs
  124. should add with object chunks and pull stream content
  125. .files.cat
  126. should cat with a base58 string encoded multihash
  127. should cat with a base58 string encoded multihash (promised)
  128. should cat with a Buffer multihash
  129. should cat with a CID object
  130. should cat a BIG file
  131. should cat with IPFS path
  132. should cat with IPFS path, nested value
  133. should error on invalid key (promised)
  134. should error on unknown path (promised)
  135. should error on dir path (promised)
  136. should export a chunk of a file
  137. .files.catReadableStream
  138. should return a Readable Stream for a CID
  139. should export a chunk of a file in a Readable Stream
  140. .files.catPullStream
  141. should return a Pull Stream for a CID
  142. should export a chunk of a file in a Pull Stream
  143. .files.get
  144. should get with a base58 encoded multihash
  145. should get with a base58 encoded multihash (promised)
  146. should get with a Buffer multihash
  147. should get a BIG file
  148. should get a directory
  149. should get with ipfs path, as object and nested value
  150. should get with ipfs path, as array and nested value
  151. should error on invalid key
  152. .files.getReadableStream
  153. should return a Readable Stream of Readable Streams
  154. .files.getPullStream
  155. should return a Pull Stream of Pull Streams
  156. .files.mkdir
  157. should make directory on root
  158. should make directory and its parents
  159. should not make already existent directory
  160. .files.write
  161. should not write to non existent file, expect error
  162. should write to non existent file with create flag
  163. should write to deeply nested non existent file with create and parents flags
  164. .files.cp
  165. should copy file, expect error
  166. should copy file, expect no error
  167. should copy dir, expect error
  168. should copy dir, expect no error
  169. .files.mv
  170. should not move not found file/dir, expect error
  171. should move file, expect no error
  172. should move dir, expect no error
  173. .files.rm
  174. should not remove not found file/dir, expect error
  175. should remove file, expect no error
  176. should remove dir, expect no error
  177. .files.stat
  178. should not stat not found file/dir, expect error
  179. - should stat file (https://github.com/ipfs/interface-ipfs-core/pull/365)
  180. - should stat dir (https://github.com/ipfs/interface-ipfs-core/pull/365)
  181. - should stat withLocal file
  182. - should stat withLocal dir
  183. - should stat outside of mfs (https://github.com/ipfs/interface-ipfs-core/pull/365)
  184. .files.read
  185. should not read not found, expect error
  186. should read file
  187. .files.readReadableStream
  188. should not read not found, expect error
  189. should read file
  190. .files.readPullStream
  191. should not read not found, expect error
  192. should read file
  193. .files.ls
  194. should not ls not found file/dir, expect error
  195. should ls directory
  196. should ls -l directory
  197. .files.flush
  198. should not flush not found file/dir, expect error
  199. should flush root
  200. should flush specific dir
  201. .key.gen
  202. should generate a new rsa key
  203. .key.list
  204. should list all the keys
  205. .key.rename
  206. should rename a key
  207. .key.rm
  208. should rm a key
  209. .key.export
  210. should export "self" key
  211. .key.import
  212. should import an exported key
  213. .ls
  214. should ls with a base58 encoded CID
  215. should correctly handle a non existing hash
  216. should correctly handle a non exiting path
  217. .lsReadableStream
  218. should readable stream ls with a base58 encoded CID
  219. .lsPullStream
  220. should pull stream ls with a base58 encoded CID
  221. .id
  222. should get the node ID
  223. should get the node ID (promised)
  224. .version
  225. should get the node version
  226. should get the node version (promised)
  227. .dns
  228. should resolve a DNS link
  229. .stop
  230. should stop the node
  231. .resolve
  232. should resolve an IPFS hash
  233. should resolve an IPFS path link
  234. should not resolve an IPFS path non-link
  235. - should resolve an IPNS DNS link (TODO IPNS not implemented yet)
  236. - should resolve IPNS link recursively (TODO IPNS not implemented yet)
  237. .name.publish
  238. should publish an IPNS record with the default params
  239. should publish correctly when the file was not added but resolve is disabled
  240. should publish with a key received as param, instead of using the key of the node
  241. .name.resolve
  242. should resolve a record with the default params after a publish
  243. should not get the entry if its validity time expired
  244. should recursively resolve to an IPFS hash
  245. .object.new
  246. should create a new object with no template
  247. should create a new object with no template (promised)
  248. should create a new object with unixfs-dir template
  249. .object.put
  250. should put an object
  251. should put an object (promised)
  252. should put a JSON encoded Buffer
  253. should put a Protobuf encoded Buffer
  254. should put a Buffer as data
  255. should put a Protobuf DAGNode
  256. should fail if a string is passed
  257. should put a Protobuf DAGNode with a link
  258. .object.get
  259. should get object by multihash
  260. should get object by multihash (promised)
  261. should get object by multihash string
  262. should get object by multihash string (promised)
  263. should get object with links by multihash string
  264. should get object by base58 encoded multihash
  265. should get object by base58 encoded multihash string
  266. supplies unadulterated data
  267. .object.data
  268. should get data by multihash
  269. should get data by multihash (promised)
  270. should get data by base58 encoded multihash
  271. should get data by base58 encoded multihash string
  272. .object.links
  273. should get empty links by multihash
  274. should get empty links by multihash (promised)
  275. should get links by multihash
  276. should get links by base58 encoded multihash
  277. should get links by base58 encoded multihash string
  278. .object.stat
  279. should get stats by multihash
  280. should get stats for object by multihash (promised)
  281. should get stats for object with links by multihash
  282. should get stats by base58 encoded multihash
  283. should get stats by base58 encoded multihash string
  284. .object.patch.addLink
  285. should add a link to an existing node
  286. should add a link to an existing node (promised)
  287. .object.patch.rmLink
  288. should remove a link from an existing node
  289. should remove a link from an existing node (promised)
  290. .object.patch.appendData
  291. should append data to an existing node
  292. should append data to an existing node (promised)
  293. .object.patch.setData
  294. should set data for an existing node
  295. should set data for an existing node (promised)
  296. .pin.ls
  297. should list recursive pins
  298. should list indirect pins
  299. should list pins
  300. should list pins (promised)
  301. should list direct pins
  302. should list pins for a specific hash
  303. should list pins for a specific hash (promised)
  304. .pin.rm
  305. should remove a recursive pin
  306. should remove a direct pin (promised)
  307. .pin.add
  308. should add a pin
  309. should add a pin (promised)
  310. .ping
  311. should send the specified number of packets
  312. - should fail when pinging an unknown peer (Timing out)
  313. should fail when pinging an invalid peer
  314. .pingPullStream
  315. should send the specified number of packets over pull stream
  316. - should fail when pinging an unknown peer over pull stream (Timing out)
  317. should fail when pinging an invalid peer over pull stream
  318. .pingReadableStream
  319. should send the specified number of packets over readable stream
  320. - should fail when pinging an unknown peer over readable stream (Timing out)
  321. should fail when pinging an invalid peer over readable stream
  322. .pubsub.publish
  323. should error on string messags
  324. should publish message from buffer
  325. should publish 10 times within time limit
  326. .pubsub.subscribe
  327. single node
  328. should subscribe to one topic
  329. should subscribe to one topic (promised)
  330. should subscribe to one topic with options
  331. should subscribe to one topic with options (promised)
  332. should subscribe to topic multiple times with different handlers
  333. should allow discover option to be passed
  334. multiple connected nodes
  335. should receive messages from a different node
  336. should round trip a non-utf8 binary buffer
  337. should receive multiple messages
  338. Send/Receive 100 messages took: 86 ms, 1162 ops / s
  339. send/receive 100 messages
  340. .pubsub.unsubscribe
  341. should subscribe and unsubscribe 10 times
  342. .pubsub.peers
  343. should not error when not subscribed to a topic
  344. should not return extra peers
  345. should return peers for a topic - one peer
  346. should return peers for a topic - multiple peers
  347. .pubsub.ls
  348. should return an empty list when no topics are subscribed
  349. should return a list with 1 subscribed topic
  350. should return a list with 3 subscribed topics
  351. .repo.version
  352. should get the repo version
  353. should get the repo version (promised)
  354. .repo.stat
  355. should get repo stats
  356. should get repo stats (promised)
  357. .repo.gc (TODO: repo.gc is not implemented in js-ipfs yet!)
  358. - should run garbage collection
  359. - should run garbage collection (promised)
  360. .stats.bitswap
  361. should get bitswap stats
  362. should get bitswap stats (promised)
  363. .stats.bw
  364. should get bandwidth stats
  365. should get bandwidth stats (promised)
  366. .stats.bwPullStream
  367. should get bandwidth stats over pull stream
  368. .stats.bwReadableStream
  369. should get bandwidth stats over readable stream
  370. .stats.repo
  371. should get repo stats
  372. should get repo stats (promised)
  373. .swarm.connect
  374. should connect to a peer
  375. should connect to a peer (promised)
  376. .swarm.peers
  377. should list peers this node is connected to
  378. should list peers this node is connected to (promised)
  379. should list peers this node is connected to with verbose option
  380. should list peers only once
  381. should list peers only once even if they have multiple addresses
  382. .swarm.addrs
  383. - should get a list of node addresses (Returning empty array)
  384. - should get a list of node addresses (promised) (Returning empty array)
  385. .swarm.localAddrs
  386. should list local addresses the node is listening on
  387. should list local addresses the node is listening on (promised)
  388. .swarm.disconnect
  389. should disconnect from a peer
  390. should disconnect from a peer (promised)
  391. .types (FIXME: currently failing)
  392. - should have a types object with the required values
  393. .util (FIXME: currently failing)
  394. - should have a util object with the required values
  395. 261 passing (2m)
  396. 37 pending

Caveats

Progress option

The progress option for files.add currently tracks progress of data streamed to the IPFS node.

Contribute

Feel free to dive in! Open an issue or submit PRs.

License

MIT © Protocol Labs