Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

feat: allow passing a http.Agent to the grpc client #3477

Merged
merged 3 commits into from
Jan 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/custom-ipld-formats/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"test-ipfs-example": "^2.0.3"
},
"dependencies": {
"cids": "^1.0.0",
"cids": "^1.1.5",
"ipfs-daemon": "^0.3.1",
"ipfs-core": "^0.3.0",
"ipfs-http-client": "^48.1.2",
Expand Down
2 changes: 1 addition & 1 deletion examples/traverse-ipld-graphs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"test-ipfs-example": "^2.0.3"
},
"dependencies": {
"cids": "^1.0.0",
"cids": "^1.1.5",
"ipfs": "^0.52.2",
"ipld-block": "^0.11.0",
"ipld-dag-pb": "^0.20.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/interface-ipfs-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"chai": "^4.2.0",
"chai-as-promised": "^7.1.1",
"chai-subset": "^1.6.0",
"cids": "^1.0.0",
"cids": "^1.1.5",
"delay": "^4.4.0",
"dirty-chai": "^2.0.1",
"err-code": "^2.0.3",
Expand Down
2 changes: 1 addition & 1 deletion packages/ipfs-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"bignumber.js": "^9.0.0",
"byteman": "^1.3.5",
"cid-tool": "^1.0.0",
"cids": "^1.0.0",
"cids": "^1.1.5",
"debug": "^4.1.1",
"err-code": "^2.0.3",
"execa": "^5.0.0",
Expand Down
1 change: 1 addition & 0 deletions packages/ipfs-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ An optional object which may have the following keys:
| ---- | ---- | ------- | ----------- |
| grpc | `Multiaddr` or `string` or `URL` | `undefined` | The address of a [ipfs-grpc-server][] to connect to |
| http | `Multiaddr` or `string` or `URL` | `undefined` | The address of a [ipfs-http-server][] to connect to |
| agent | [http.Agent](https://nodejs.org/api/http.html#http_class_http_agent) | `undefined` | A http.Agent used to control HTTP client behaviour (node.js only) |

### Returns

Expand Down
2 changes: 1 addition & 1 deletion packages/ipfs-core-types/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
],
"license": "(Apache-2.0 OR MIT)",
"dependencies": {
"cids": "^1.0.0",
"cids": "^1.1.5",
"multiaddr": "^8.0.0",
"peer-id": "^0.14.1"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/ipfs-core-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"any-signal": "^2.0.0",
"blob-to-it": "^1.0.1",
"browser-readablestream-to-it": "^1.0.1",
"cids": "^1.0.0",
"cids": "^1.1.5",
"err-code": "^2.0.3",
"ipfs-utils": "^5.0.0",
"ipfs-core-types": "^0.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/ipfs-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"array-shuffle": "^1.0.1",
"bignumber.js": "^9.0.0",
"cbor": "^5.1.0",
"cids": "^1.0.0",
"cids": "^1.1.5",
"class-is": "^1.1.0",
"dag-cbor-links": "^2.0.0",
"datastore-core": "^2.0.0",
Expand Down
1 change: 1 addition & 0 deletions packages/ipfs-grpc-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ An optional object which may have the following keys:
| Name | Type | Default | Description |
| ---- | ---- | ------- | ----------- |
| url | `Multiaddr` or `string` or `URL` | `undefined` | The address of a [ipfs-grpc-server][] to connect to |
| agent | [http.Agent](https://nodejs.org/api/http.html#http_class_http_agent) | `undefined` | A http.Agent used to control HTTP client behaviour (node.js only) |

### Returns

Expand Down
2 changes: 1 addition & 1 deletion packages/ipfs-grpc-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"dependencies": {
"@improbable-eng/grpc-web": "^0.13.0",
"change-case": "^4.1.1",
"cids": "^1.0.0",
"cids": "^1.1.5",
"debug": "^4.1.1",
"err-code": "^2.0.3",
"ipfs-core-utils": "^0.5.0",
Expand Down
3 changes: 2 additions & 1 deletion packages/ipfs-grpc-client/src/core-api/add-all.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ module.exports = function grpcAddAll (grpc, service, opts = {}) {
} = bidiToDuplex(grpc, service, {
host: opts.url,
debug: Boolean(process.env.DEBUG),
metadata: options
metadata: options,
agent: opts.agent
})

sendFiles(stream, sink)
Expand Down
3 changes: 2 additions & 1 deletion packages/ipfs-grpc-client/src/core-api/files/ls.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ module.exports = function grpcMfsLs (grpc, service, opts = {}) {
for await (const result of serverStreamToIterator(grpc, service, request, {
host: opts.url,
debug: Boolean(process.env.DEBUG),
metadata: options
metadata: options,
agent: opts.agent
})) {
yield {
name: result.name,
Expand Down
3 changes: 2 additions & 1 deletion packages/ipfs-grpc-client/src/core-api/files/write.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ module.exports = function grpcMfsWrite (grpc, service, opts = {}) {
await clientStreamToPromise(grpc, service, stream(path, content), {
host: opts.url,
debug: Boolean(process.env.DEBUG),
metadata: options
metadata: options,
agent: opts.agent
})
}

Expand Down
3 changes: 2 additions & 1 deletion packages/ipfs-grpc-client/src/core-api/id.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ module.exports = function grpcId (grpc, service, opts = {}) {

const res = await unaryToPromise(grpc, service, request, {
host: opts.url,
metadata: toHeaders(options)
metadata: toHeaders(options),
agent: opts.agent
})

return {
Expand Down
31 changes: 26 additions & 5 deletions packages/ipfs-grpc-client/src/grpc/transport.node.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,32 @@ const WebsocketSignal = {

const finishSendFrame = new Uint8Array([1])

function WebsocketTransport () {
return (opts) => {
return websocketRequest(opts)
/**
* @param {object} options
* @param {import('http').Agent} [options.agent] - http.Agent used to control HTTP client behaviour
*/
function WebsocketTransport (options) {
/**
* @param {import('@improbable-eng/grpc-web').grpc.TransportOptions} opts
*/
const websocketTransportFactory = (opts) => {
return websocketRequest({
...options,
...opts
})
}

return websocketTransportFactory
}

/**
* @typedef {object} NodeTransportOptions
* @property {import('http').Agent} [options.agent]
*
* @typedef {NodeTransportOptions & import('@improbable-eng/grpc-web').grpc.TransportOptions} WebSocketTransportOptions
*
* @param {WebSocketTransportOptions} options
*/
function websocketRequest (options) {
const webSocketAddress = constructWebSocketAddress(options.url)

Expand Down Expand Up @@ -54,7 +74,7 @@ function websocketRequest (options) {
}
},
start: (metadata) => {
ws = new WebSocket(webSocketAddress, ['grpc-websockets'])
ws = new WebSocket(webSocketAddress, ['grpc-websockets'], options)
ws.binaryType = 'arraybuffer'
ws.onopen = function () {
options.debug && debug('websocketRequest.onopen')
Expand Down Expand Up @@ -93,7 +113,8 @@ function constructWebSocketAddress (url) {
} else if (url.substr(0, 7) === 'http://') {
return `ws://${url.substr(7)}`
}
throw new Error('Websocket transport constructed with non-https:// or http:// host.')

throw new Error('Websocket transport url must start with ws:// or wss:// or http:// or https://')
}

function headersToBytes (headers) {
Expand Down
9 changes: 6 additions & 3 deletions packages/ipfs-grpc-client/src/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
'use strict'

const transport = require('./grpc/transport')
const toUrlString = require('ipfs-core-utils/src/to-url-string')
const loadServices = require('./utils/load-services')
const { grpc } = require('@improbable-eng/grpc-web')
grpc.setDefaultTransport(transport())

const service = loadServices()

Expand All @@ -21,7 +19,12 @@ function normaliseUrls (opts) {
})
}

module.exports = function createClient (opts = {}) {
/**
* @param {object} opts
* @param {string} opts.url - The URL to connect to as a URL or Multiaddr
* @param {import('http').Agent} [opts.agent] - http.Agent used to control HTTP client behaviour (node.js only)
*/
module.exports = function createClient (opts = { url: '' }) {
opts.url = toUrlString(opts.url)

// @improbable-eng/grpc-web requires http:// protocol URLs, not ws://
Expand Down
9 changes: 8 additions & 1 deletion packages/ipfs-grpc-client/src/utils/bidi-to-duplex.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const pushable = require('it-pushable')
const errCode = require('err-code')
const toHeaders = require('./to-headers')
const transport = require('../grpc/transport')

async function sendMessages (service, client, source) {
for await (const obj of source) {
Expand All @@ -23,6 +24,7 @@ async function sendMessages (service, client, source) {
* @param {string} options.host - The remote host
* @param {boolean} [options.debug] - Whether to print debug messages
* @param {object} [options.metadata] - Metadata sent as headers
* @param {import('http').Agent} [options.agent] - http.Agent used to control HTTP client behaviour (node.js only)
* @returns {{ source: AsyncIterable<object>, sink: { push: Function, end: Function } }}
**/
module.exports = function bidiToDuplex (grpc, service, options) {
Expand All @@ -32,7 +34,12 @@ module.exports = function bidiToDuplex (grpc, service, options) {
// @ts-ignore
const sink = pushable()

const client = grpc.client(service, options)
const client = grpc.client(service, {
...options,
transport: transport({
agent: options.agent
})
})
client.onMessage(message => {
sink.push(message)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const bidiToDuplex = require('./bidi-to-duplex')
* @param {string} options.host - The remote host
* @param {boolean} [options.debug] - Whether to print debug messages
* @param {object} [options.metadata] - Metadata sent as headers
* @param {import('http').Agent} [options.agent] - http.Agent used to control HTTP client behaviour (node.js only)
* @returns {Promise<Object>} - A promise that resolves to a response object
**/
module.exports = async function clientStreamToPromise (grpc, service, source, options) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const bidiToDuplex = require('./bidi-to-duplex')
* @param {string} options.host - The remote host
* @param {boolean} [options.debug] - Whether to print debug messages
* @param {object} [options.metadata] - Metadata sent as headers
* @param {import('http').Agent} [options.agent] - http.Agent used to control HTTP client behaviour (node.js only)
* @returns {AsyncIterable<object>}
**/
module.exports = function serverStreamToIterator (grpc, service, request, options) {
Expand Down
1 change: 1 addition & 0 deletions packages/ipfs-grpc-client/src/utils/unary-to-promise.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const bidiToDuplex = require('./bidi-to-duplex')
* @param {string} options.host - The remote host
* @param {boolean} [options.debug] - Whether to print debug messages
* @param {object} [options.metadata] - Metadata sent as headers
* @param {import('http').Agent} [options.agent] - http.Agent used to control HTTP client behaviour (node.js only)
* @returns {Promise<Object>} - A promise that resolves to a response object
**/
module.exports = function unaryToPromise (grpc, service, request, options) {
Expand Down
49 changes: 49 additions & 0 deletions packages/ipfs-grpc-client/test/agent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* eslint-env mocha */
'use strict'

const grpcClient = require('../src')
const WebSocket = require('ws')

function startServer () {
return new Promise((resolve) => {
const wss = new WebSocket.Server({ port: 0 })

wss.on('listening', () => {
resolve({
port: wss.address().port,
close: () => wss.close()
})
})

wss.on('connection', (ws) => {
ws.once('message', () => {
ws.send('')
ws.end()
})
})
})
}

describe('agent', function () {
it('uses the passed agent', async () => {
const server = await startServer()

try {
await new Promise((resolve) => {
const ipfs = grpcClient({
url: `http://localhost:${server.port}`,
agent: {
addRequest () {
// an agent method was invoked
resolve()
}
}
})

ipfs.id().catch(() => {})
})
} finally {
server.close()
}
})
})
3 changes: 3 additions & 0 deletions packages/ipfs-grpc-client/test/node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
'use strict'

require('./agent')
2 changes: 1 addition & 1 deletion packages/ipfs-http-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"dependencies": {
"any-signal": "^2.0.0",
"bignumber.js": "^9.0.0",
"cids": "^1.0.0",
"cids": "^1.1.5",
"debug": "^4.1.1",
"form-data": "^3.0.0",
"ipfs-core-utils": "^0.5.4",
Expand Down
1 change: 0 additions & 1 deletion packages/ipfs-http-client/src/dag/put.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ module.exports = configure((api, opts) => {
const cid = new CID(options.cid)
encodingOptions = {
...options,
// @ts-expect-error - https://github.com/multiformats/js-cid/pull/138
format: multicodec.getName(cid.code),
hashAlg: multihash.decode(cid.multihash).name
}
Expand Down
5 changes: 5 additions & 0 deletions packages/ipfs-http-client/test/node/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ describe('agent', function () {

break
}

if (i === 4) {
// should have first two responses by now
expect(responses).to.have.lengthOf(2)
}
}

// wait for the final request to arrive
Expand Down
2 changes: 1 addition & 1 deletion packages/ipfs-http-gateway/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"@hapi/ammo": "^5.0.1",
"@hapi/boom": "^9.1.0",
"@hapi/hapi": "^20.0.0",
"cids": "^1.0.0",
"cids": "^1.1.5",
"debug": "^4.1.1",
"hapi-pino": "^8.3.0",
"ipfs-core-utils": "^0.5.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/ipfs-http-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"@hapi/boom": "^9.1.0",
"@hapi/content": "^5.0.2",
"@hapi/hapi": "^20.0.0",
"cids": "^1.0.0",
"cids": "^1.1.5",
"debug": "^4.1.1",
"dlv": "^1.1.3",
"err-code": "^2.0.3",
Expand Down
2 changes: 1 addition & 1 deletion packages/ipfs-message-port-protocol/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"dep-check": "aegir dep-check -i typescript -i rimraf"
},
"dependencies": {
"cids": "^1.0.0",
"cids": "^1.1.5",
"ipld-block": "^0.11.0"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/ipfs-message-port-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"devDependencies": {
"@types/it-all": "^1.0.0",
"aegir": "^29.2.2",
"cids": "^1.0.0",
"cids": "^1.1.5",
"ipfs-utils": "^5.0.0",
"rimraf": "^3.0.2",
"typescript": "4.0.x"
Expand Down