Skip to content

Commit

Permalink
fix(adapter-node-http): Correctly handle uploading binary data (#257)
Browse files Browse the repository at this point in the history
  • Loading branch information
swashcap authored and offirgolan committed Nov 21, 2019
1 parent 5d42cbd commit 31f0e0a
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 11 deletions.
2 changes: 2 additions & 0 deletions packages/@pollyjs/adapter-node-http/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
"devDependencies": {
"@pollyjs/core": "^2.6.3",
"@pollyjs/persister-fs": "^2.6.3",
"form-data": "^2.5.1",
"get-stream": "^5.1.0",
"node-fetch": "^2.6.0",
"rollup": "^1.14.6"
}
Expand Down
2 changes: 1 addition & 1 deletion packages/@pollyjs/adapter-node-http/rollup.config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import createJestTestConfig from '../../../scripts/rollup/jest.test.config';

import { external } from './rollup.config.shared';

const testExternal = [...external, 'crypto'];
const testExternal = [...external, 'crypto', 'fs', 'path'];

export default [
createNodeTestConfig({ external: testExternal }),
Expand Down
16 changes: 7 additions & 9 deletions packages/@pollyjs/adapter-node-http/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,15 @@ export default class HttpAdapter extends Adapter {
...REQUEST_ARGUMENTS.get(req)
);
const url = getUrlFromOptions(parsedArguments.options);
const contentType = (headers['content-type'] || '').toString();
const isMultiPart = contentType.includes('multipart');

if (body) {
if (isMultiPart && Buffer.isBuffer(body)) {
// Nock can return a hex-encoded body multipart/form-data
if (!isUtf8Representable(body)) {
body = Buffer.from(body, 'hex');
}

body = body.toString();
if (
typeof body === 'string' &&
!isUtf8Representable(Buffer.from(body, 'hex'))
) {
// Nock internally converts a binary buffer into its hexadecimal
// representation so convert it back to a buffer.
body = Buffer.from(body, 'hex');
} else if (isJSONContent(headers)) {
// Nock will parse json content into an object. We have our own way
// of dealing with json content so convert it back to a string.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import fs from 'fs';
import http from 'http';
import https from 'https';
import path from 'path';

import FormData from 'form-data';
import getStream from 'get-stream';
import adapterIdentifierTests from '@pollyjs-tests/integration/adapter-identifier-tests';
import setupFetchRecord from '@pollyjs-tests/helpers/setup-fetch-record';
import adapterTests from '@pollyjs-tests/integration/adapter-tests';
Expand Down Expand Up @@ -69,7 +73,7 @@ describe('Integration | Node Http Adapter', function() {
function commonTests(transport) {
const { protocol } = transport.globalAgent;

it('should handle posting a buffer', async function() {
it('should be able to upload a binary data', async function() {
const { server } = this.polly;
const url = `${protocol}//example.com`;
const body = Buffer.from('Node HTTP Adapter', 'base64');
Expand All @@ -85,9 +89,40 @@ function commonTests(transport) {

expect(requests).to.have.lengthOf(2);
expect(requests[0].id).to.equal(requests[1].id);
expect(requests[0].body.toString('base64')).to.equal(
body.toString('base64')
);
expect(requests[0].identifiers.body).to.equal(body.toString('hex'));
});

it('should be able to upload form data', async function() {
const url = `${protocol}//example.com/upload`;
const { server } = this.polly;
const formData = new FormData();
let request;

server.post(url).intercept((req, res) => {
request = req;
res.send(201);
});

formData.append(
'upload',
fs.createReadStream(path.resolve(__dirname, '../../package.json'))
);
const body = await getStream(formData);

await nativeRequest(transport, url, {
body,
headers: formData.getHeaders(),
method: 'POST'
});

expect(request).to.exist;
expect(typeof request.body).to.equal('string');
expect(request.body).to.include('@pollyjs/adapter-node-http');
});

it('should be able to download binary content', async function() {
const url = `${protocol}//via.placeholder.com/150/92c952`;
const { server } = this.polly;
Expand Down
9 changes: 9 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6834,6 +6834,15 @@ forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"

form-data@^2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.6"
mime-types "^2.1.12"

form-data@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
Expand Down

0 comments on commit 31f0e0a

Please sign in to comment.