[Backport 7.x] Support mapbox content type (#1508)
Co-authored-by: Tomas Della Vedova <delvedor@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
a287c71147
commit
563b7746cd
@ -32,3 +32,10 @@ class MyTransport extends Transport {
|
|||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
|
||||||
|
==== Supported content types
|
||||||
|
|
||||||
|
- `application/json`, in this case the transport will return a plain JavaScript object
|
||||||
|
- `text/plain`, in this case the transport will return a plain string
|
||||||
|
- `application/vnd.mapbox-vector-tile`, in this case the transport will return a Buffer
|
||||||
|
- `application/vnd.elasticsearch+json`, in this case the transport will return a plain JavaScript object
|
||||||
|
|
||||||
|
|||||||
4
lib/Transport.d.ts
vendored
4
lib/Transport.d.ts
vendored
@ -155,8 +155,8 @@ export default class Transport {
|
|||||||
_nextSniff: number;
|
_nextSniff: number;
|
||||||
_isSniffing: boolean;
|
_isSniffing: boolean;
|
||||||
constructor(opts: TransportOptions);
|
constructor(opts: TransportOptions);
|
||||||
request(params: TransportRequestParams, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse>;
|
request<TResponse = Record<string, any>, TContext = Context>(params: TransportRequestParams, options?: TransportRequestOptions): TransportRequestPromise<ApiResponse<TResponse, TContext>>;
|
||||||
request(params: TransportRequestParams, options?: TransportRequestOptions, callback?: (err: ApiError, result: ApiResponse) => void): TransportRequestCallback;
|
request<TResponse = Record<string, any>, TContext = Context>(params: TransportRequestParams, options?: TransportRequestOptions, callback?: (err: ApiError, result: ApiResponse<TResponse, TContext>) => void): TransportRequestCallback;
|
||||||
getConnection(opts: TransportGetConnectionOptions): Connection | null;
|
getConnection(opts: TransportGetConnectionOptions): Connection | null;
|
||||||
sniff(opts?: TransportSniffOptions, callback?: (...args: any[]) => void): void;
|
sniff(opts?: TransportSniffOptions, callback?: (...args: any[]) => void): void;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -237,6 +237,7 @@ class Transport {
|
|||||||
|
|
||||||
const contentEncoding = (result.headers['content-encoding'] || '').toLowerCase()
|
const contentEncoding = (result.headers['content-encoding'] || '').toLowerCase()
|
||||||
const isCompressed = contentEncoding.indexOf('gzip') > -1 || contentEncoding.indexOf('deflate') > -1
|
const isCompressed = contentEncoding.indexOf('gzip') > -1 || contentEncoding.indexOf('deflate') > -1
|
||||||
|
const isVectorTile = (result.headers['content-type'] || '').indexOf('application/vnd.mapbox-vector-tile') > -1
|
||||||
|
|
||||||
/* istanbul ignore else */
|
/* istanbul ignore else */
|
||||||
if (result.headers['content-length'] !== undefined) {
|
if (result.headers['content-length'] !== undefined) {
|
||||||
@ -255,8 +256,9 @@ class Transport {
|
|||||||
}
|
}
|
||||||
// if the response is compressed, we must handle it
|
// if the response is compressed, we must handle it
|
||||||
// as buffer for allowing decompression later
|
// as buffer for allowing decompression later
|
||||||
let payload = isCompressed ? [] : ''
|
// while if it's a vector tile, we should return it as buffer
|
||||||
const onData = isCompressed
|
let payload = isCompressed || isVectorTile ? [] : ''
|
||||||
|
const onData = isCompressed || isVectorTile
|
||||||
? chunk => { payload.push(chunk) }
|
? chunk => { payload.push(chunk) }
|
||||||
: chunk => { payload += chunk }
|
: chunk => { payload += chunk }
|
||||||
const onEnd = err => {
|
const onEnd = err => {
|
||||||
@ -272,7 +274,7 @@ class Transport {
|
|||||||
if (isCompressed) {
|
if (isCompressed) {
|
||||||
unzip(Buffer.concat(payload), onBody)
|
unzip(Buffer.concat(payload), onBody)
|
||||||
} else {
|
} else {
|
||||||
onBody(null, payload)
|
onBody(null, isVectorTile ? Buffer.concat(payload) : payload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,7 +283,7 @@ class Transport {
|
|||||||
onEnd(new Error('Response aborted while reading the body'))
|
onEnd(new Error('Response aborted while reading the body'))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isCompressed) {
|
if (!isCompressed && !isVectorTile) {
|
||||||
response.setEncoding('utf8')
|
response.setEncoding('utf8')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,7 +299,9 @@ class Transport {
|
|||||||
this.emit('response', err, result)
|
this.emit('response', err, result)
|
||||||
return callback(err, result)
|
return callback(err, result)
|
||||||
}
|
}
|
||||||
if (Buffer.isBuffer(payload)) {
|
|
||||||
|
const isVectorTile = (result.headers['content-type'] || '').indexOf('application/vnd.mapbox-vector-tile') > -1
|
||||||
|
if (Buffer.isBuffer(payload) && !isVectorTile) {
|
||||||
payload = payload.toString()
|
payload = payload.toString()
|
||||||
}
|
}
|
||||||
const isHead = params.method === 'HEAD'
|
const isHead = params.method === 'HEAD'
|
||||||
|
|||||||
@ -2689,3 +2689,76 @@ test('The callback with a sync error should be called in the next tick - ndjson'
|
|||||||
t.type(transportReturn.catch, 'function')
|
t.type(transportReturn.catch, 'function')
|
||||||
t.type(transportReturn.abort, 'function')
|
t.type(transportReturn.abort, 'function')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Support mapbox vector tile', t => {
|
||||||
|
t.plan(2)
|
||||||
|
const mvtContent = 'GoMCCgRtZXRhEikSFAAAAQACAQMBBAAFAgYDBwAIBAkAGAMiDwkAgEAagEAAAP8//z8ADxoOX3NoYXJkcy5mYWlsZWQaD19zaGFyZHMuc2tpcHBlZBoSX3NoYXJkcy5zdWNjZXNzZnVsGg1fc2hhcmRzLnRvdGFsGhlhZ2dyZWdhdGlvbnMuX2NvdW50LmNvdW50GhdhZ2dyZWdhdGlvbnMuX2NvdW50LnN1bRoTaGl0cy50b3RhbC5yZWxhdGlvbhoQaGl0cy50b3RhbC52YWx1ZRoJdGltZWRfb3V0GgR0b29rIgIwACICMAIiCRkAAAAAAAAAACIECgJlcSICOAAogCB4Ag=='
|
||||||
|
|
||||||
|
function handler (req, res) {
|
||||||
|
res.setHeader('Content-Type', 'application/vnd.mapbox-vector-tile')
|
||||||
|
res.end(Buffer.from(mvtContent, 'base64'))
|
||||||
|
}
|
||||||
|
|
||||||
|
buildServer(handler, ({ port }, server) => {
|
||||||
|
const pool = new ConnectionPool({ Connection })
|
||||||
|
pool.addConnection(`http://localhost:${port}`)
|
||||||
|
|
||||||
|
const transport = new Transport({
|
||||||
|
emit: () => {},
|
||||||
|
connectionPool: pool,
|
||||||
|
serializer: new Serializer(),
|
||||||
|
maxRetries: 3,
|
||||||
|
requestTimeout: 30000,
|
||||||
|
sniffInterval: false,
|
||||||
|
sniffOnStart: false
|
||||||
|
})
|
||||||
|
skipProductCheck(transport)
|
||||||
|
|
||||||
|
transport.request({
|
||||||
|
method: 'GET',
|
||||||
|
path: '/hello'
|
||||||
|
}, (err, { body }) => {
|
||||||
|
t.error(err)
|
||||||
|
t.same(body.toString('base64'), Buffer.from(mvtContent, 'base64').toString('base64'))
|
||||||
|
server.stop()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Compressed mapbox vector tile', t => {
|
||||||
|
t.plan(2)
|
||||||
|
const mvtContent = 'GoMCCgRtZXRhEikSFAAAAQACAQMBBAAFAgYDBwAIBAkAGAMiDwkAgEAagEAAAP8//z8ADxoOX3NoYXJkcy5mYWlsZWQaD19zaGFyZHMuc2tpcHBlZBoSX3NoYXJkcy5zdWNjZXNzZnVsGg1fc2hhcmRzLnRvdGFsGhlhZ2dyZWdhdGlvbnMuX2NvdW50LmNvdW50GhdhZ2dyZWdhdGlvbnMuX2NvdW50LnN1bRoTaGl0cy50b3RhbC5yZWxhdGlvbhoQaGl0cy50b3RhbC52YWx1ZRoJdGltZWRfb3V0GgR0b29rIgIwACICMAIiCRkAAAAAAAAAACIECgJlcSICOAAogCB4Ag=='
|
||||||
|
|
||||||
|
function handler (req, res) {
|
||||||
|
const body = gzipSync(Buffer.from(mvtContent, 'base64'))
|
||||||
|
res.setHeader('Content-Type', 'application/vnd.mapbox-vector-tile')
|
||||||
|
res.setHeader('Content-Encoding', 'gzip')
|
||||||
|
res.setHeader('Content-Length', Buffer.byteLength(body))
|
||||||
|
res.end(body)
|
||||||
|
}
|
||||||
|
|
||||||
|
buildServer(handler, ({ port }, server) => {
|
||||||
|
const pool = new ConnectionPool({ Connection })
|
||||||
|
pool.addConnection(`http://localhost:${port}`)
|
||||||
|
|
||||||
|
const transport = new Transport({
|
||||||
|
emit: () => {},
|
||||||
|
connectionPool: pool,
|
||||||
|
serializer: new Serializer(),
|
||||||
|
maxRetries: 3,
|
||||||
|
requestTimeout: 30000,
|
||||||
|
sniffInterval: false,
|
||||||
|
sniffOnStart: false
|
||||||
|
})
|
||||||
|
skipProductCheck(transport)
|
||||||
|
|
||||||
|
transport.request({
|
||||||
|
method: 'GET',
|
||||||
|
path: '/hello'
|
||||||
|
}, (err, { body }) => {
|
||||||
|
t.error(err)
|
||||||
|
t.same(body.toString('base64'), Buffer.from(mvtContent, 'base64').toString('base64'))
|
||||||
|
server.stop()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user