Skip to content

Commit

Permalink
Do not alter options.body
Browse files Browse the repository at this point in the history
Fixes #1165
  • Loading branch information
szmarczak committed Apr 22, 2020
1 parent 8501c69 commit 835c70b
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 17 deletions.
24 changes: 15 additions & 9 deletions source/core/index.ts
Expand Up @@ -41,6 +41,7 @@ const kCancelTimeouts = Symbol('cancelTimeouts');
const kStartedReading = Symbol('startedReading');
const kStopReading = Symbol('stopReading');
const kTriggerRead = Symbol('triggerRead');
const kBody = Symbol('body');
export const kIsNormalizedAlready = Symbol('isNormalizedAlready');

const supportsBrotli = is.string((process.versions as any).brotli);
Expand Down Expand Up @@ -452,6 +453,7 @@ export default class Request extends Duplex implements RequestEvents<Request> {
[kUploadedSize]: number;
[kStopReading]: boolean;
[kTriggerRead]: boolean;
[kBody]: Options['body'];
[kBodySize]?: number;
[kServerResponsesPiped]: Set<ServerResponse>;
[kIsFromCache]?: boolean;
Expand Down Expand Up @@ -889,21 +891,23 @@ export default class Request extends Duplex implements RequestEvents<Request> {
if (isFormData(options.body) && noContentType) {
headers['content-type'] = `multipart/form-data; boundary=${options.body.getBoundary()}`;
}

this[kBody] = options.body;
} else if (isForm) {
if (noContentType) {
headers['content-type'] = 'application/x-www-form-urlencoded';
}

options.body = (new URLSearchParams(options.form as Record<string, string>)).toString();
this[kBody] = (new URLSearchParams(options.form as Record<string, string>)).toString();
} else {
if (noContentType) {
headers['content-type'] = 'application/json';
}

options.body = JSON.stringify(options.json);
this[kBody] = JSON.stringify(options.json);
}

const uploadBodySize = await getBodySize(options);
const uploadBodySize = await getBodySize(this[kBody], options.headers);

// See https://tools.ietf.org/html/rfc7230#section-3.3.2
// A user agent SHOULD send a Content-Length in a request message when
Expand Down Expand Up @@ -1149,21 +1153,23 @@ export default class Request extends Duplex implements RequestEvents<Request> {
this.emit('uploadProgress', this.uploadProgress);

// Send body
const body = this[kBody];
const currentRequest = this.redirects.length === 0 ? this : request;
if (is.nodeStream(options.body)) {
options.body.pipe(currentRequest);
options.body.once('error', (error: NodeJS.ErrnoException) => {

if (is.nodeStream(body)) {
body.pipe(currentRequest);
body.once('error', (error: NodeJS.ErrnoException) => {
this._beforeError(new UploadError(error, this));
});

options.body.once('end', () => {
body.once('end', () => {
delete options.body;
});
} else {
this._unlockWrite();

if (!is.undefined(options.body)) {
this._writeRequest(options.body, null as unknown as string, () => {});
if (!is.undefined(body)) {
this._writeRequest(body, null as unknown as string, () => {});
currentRequest.end();

this._lockWrite();
Expand Down
9 changes: 1 addition & 8 deletions source/core/utils/get-body-size.ts
Expand Up @@ -4,16 +4,9 @@ import {ClientRequestArgs} from 'http';
import is from '@sindresorhus/is';
import isFormData from './is-form-data';

interface Options {
body?: unknown;
headers: ClientRequestArgs['headers'];
}

const statAsync = promisify(stat);

export default async (options: Options): Promise<number | undefined> => {
const {body, headers} = options;

export default async (body: unknown, headers: ClientRequestArgs['headers']): Promise<number | undefined> => {
if (headers && 'content-length' in headers) {
return Number(headers['content-length']);
}
Expand Down

0 comments on commit 835c70b

Please sign in to comment.