Skip to content

Commit 850773c

Browse files
authoredSep 2, 2022
Support FormData without known length (#2120)
1 parent 5c2ff68 commit 850773c

File tree

6 files changed

+49
-8
lines changed

6 files changed

+49
-8
lines changed
 

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"cacheable-lookup": "^6.0.4",
5252
"cacheable-request": "^7.0.2",
5353
"decompress-response": "^6.0.0",
54-
"form-data-encoder": "^2.0.1",
54+
"form-data-encoder": "^2.1.0",
5555
"get-stream": "^6.0.1",
5656
"http2-wrapper": "^2.1.10",
5757
"lowercase-keys": "^3.0.0",

‎source/core/index.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,9 @@ export default class Request extends Duplex implements RequestEvents<Request> {
574574
headers['content-type'] = encoder.headers['Content-Type'];
575575
}
576576

577-
headers['content-length'] = encoder.headers['Content-Length'];
577+
if ('Content-Length' in encoder.headers) {
578+
headers['content-length'] = encoder.headers['Content-Length'];
579+
}
578580

579581
options.body = encoder.encode();
580582
}

‎test/helpers/create-https-test-server.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {SecureContextOptions} from 'tls';
55
import express from 'express';
66
import pify from 'pify';
77
import pem from 'pem';
8+
import type {CreateCsr, CreateCertificate} from '../types/pem.js';
89

910
export type HttpsServerOptions = {
1011
commonName?: string;
@@ -25,8 +26,8 @@ export type ExtendedHttpsTestServer = {
2526
} & express.Express;
2627

2728
const createHttpsTestServer = async (options: HttpsServerOptions = {}): Promise<ExtendedHttpsTestServer> => {
28-
const createCsr = pify(pem.createCSR);
29-
const createCertificate = pify(pem.createCertificate);
29+
const createCsr = pify(pem.createCSR as CreateCsr);
30+
const createCertificate = pify(pem.createCertificate as CreateCertificate);
3031

3132
const caCsrResult = await createCsr({commonName: 'authority'});
3233
const caResult = await createCertificate({
@@ -68,7 +69,7 @@ const createHttpsTestServer = async (options: HttpsServerOptions = {}): Promise<
6869

6970
await pify(server.https.listen.bind(server.https))();
7071

71-
server.caKey = caKey;
72+
server.caKey = caKey as any;
7273
server.caCert = caCert;
7374
server.port = (server.https.address() as net.AddressInfo).port;
7475
server.url = `https://localhost:${(server.port)}`;

‎test/https.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import pify from 'pify';
66
import pem from 'pem';
77
import got from '../source/index.js';
88
import {withHttpsServer} from './helpers/with-server.js';
9+
import type {CreatePrivateKey, CreateCsr, CreateCertificate} from './types/pem.js';
910

10-
const createPrivateKey = pify(pem.createPrivateKey);
11-
const createCsr = pify(pem.createCSR);
12-
const createCertificate = pify(pem.createCertificate);
11+
const createPrivateKey = pify(pem.createPrivateKey as CreatePrivateKey);
12+
const createCsr = pify(pem.createCSR as CreateCsr);
13+
const createCertificate = pify(pem.createCertificate as CreateCertificate);
1314
const createPkcs12 = pify(pem.createPkcs12);
1415

1516
test('https request without ca', withHttpsServer(), async (t, server, got) => {

‎test/post.ts

+30
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,36 @@ test('body - sends files with spec-compliant FormData', withServer, async (t, se
361361
t.deepEqual(body, expected);
362362
});
363363

364+
test('body - sends form-data with without known length', withServer, async (t, server, got) => {
365+
server.post('/', echoMultipartBody);
366+
const fullPath = path.resolve('test/fixtures/ok');
367+
368+
function getFileStream() {
369+
const fileStream = fs.createReadStream(fullPath);
370+
const passThrough = new stream.PassThrough();
371+
fileStream.pipe(passThrough);
372+
return passThrough;
373+
}
374+
375+
const expected = {
376+
file: await fsPromises.readFile(fullPath, 'utf8'),
377+
};
378+
379+
const form = new FormDataNode();
380+
form.set('file', {
381+
[Symbol.toStringTag]: 'File',
382+
type: 'text/plain',
383+
name: 'file.txt',
384+
stream() {
385+
return getFileStream();
386+
},
387+
});
388+
389+
const body = await got.post({body: form}).json<typeof expected>();
390+
391+
t.deepEqual(body, expected);
392+
});
393+
364394
test('throws on upload error', withServer, async (t, server, got) => {
365395
server.post('/', defaultEndpoint);
366396

‎test/types/pem.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import type {CertificateCreationOptions, CertificateCreationResult, PrivateKeyCreationOptions, CSRCreationOptions, Callback} from 'pem';
2+
3+
export type CreateCertificate = (options: CertificateCreationOptions, callback: Callback<CertificateCreationResult>) => void;
4+
5+
export type CreateCsr = (options: CSRCreationOptions, callback: Callback<{csr: string; clientKey: string}>) => void;
6+
7+
export type CreatePrivateKey = (keyBitsize: number, options: PrivateKeyCreationOptions, callback: Callback<{key: string}>) => void;

0 commit comments

Comments
 (0)
Please sign in to comment.