nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: sindresorhus/got
Pull request #339 (2017-06-24 12:31:17)

Fix unix address parser
When request
```
unix:/var/run/docker.sock:/images/alpine:latest/json
```
It will return socketPath `unix:/var/run/docker.sock:/images/alpine`

so fix regex to `(.+?):(.+)`

sindresorhus: Can you add a test?
Dreamacro: Sorry, create additional test cases now.

Patch:
diff --git a/index.js b/index.js
index 4ad2067..4c5090a 100644
--- a/index.js
+++ b/index.js
@@ -342,7 +342,7 @@ function normalizeArguments(url, opts) {
 	}
 
 	if (opts.hostname === 'unix') {
-		const matches = /(.+):(.+)/.exec(opts.path);
+		const matches = /(.+?):(.+)/.exec(opts.path);
 
 		if (matches) {
 			opts.socketPath = matches[1];


Test patch:
diff --git a/test/error.js b/test/error.js
index 2f5efb0..0d819b0 100644
--- a/test/error.js
+++ b/test/error.js
@@ -40,7 +40,7 @@ test('dns message', async t => {
 
 test('options.body error message', async t => {
 	const err = await t.throws(got(s.url, {body: () => {}}));
-	t.regex(err.message, /options.body must be a ReadableStream, string, Buffer or plain Object/);
+	t.regex(err.message, /options\.body must be a ReadableStream, string, Buffer or plain Object/);
 });
 
 test.after('cleanup', async () => {
diff --git a/test/unix-socket.js b/test/unix-socket.js
index 6b556a6..ba32935 100644
--- a/test/unix-socket.js
+++ b/test/unix-socket.js
@@ -15,6 +15,10 @@ test.before('setup', async () => {
 		res.end('ok');
 	});
 
+	s.on('/foo:bar', (req, res) => {
+		res.end('ok');
+	});
+
 	await s.listen(socketPath);
 });
 
@@ -28,6 +32,11 @@ test('protocol-less works', async t => {
 	t.is((await got(url)).body, 'ok');
 });
 
+test('address with : works', async t => {
+	const url = format('unix:%s:%s', socketPath, '/foo:bar');
+	t.is((await got(url)).body, 'ok');
+});
+
 test.after('cleanup', async () => {
 	await s.close();
 });
Repository: sindresorhus/got
Pull request #378 (2017-09-22 09:54:36)

Expose CancelError
Expose `CancelError` from `p-cancelable` as `got.CancelError`. The alternative is to keep the original promise in the chain to test if the request is cancelled or to import `p-cancelable`, which might not be the same package imported by `got`.


Patch:
diff --git a/index.js b/index.js
index e11bfd2..14a5879 100644
--- a/index.js
+++ b/index.js
@@ -640,4 +640,6 @@ got.UnsupportedProtocolError = class extends StdError {
 	}
 };
 
+got.CancelError = PCancelable.CancelError;
+
 module.exports = got;
diff --git a/readme.md b/readme.md
index 2ac7fc1..16b1c4a 100644
--- a/readme.md
+++ b/readme.md
@@ -277,6 +277,10 @@ When server redirects you more than 10 times. Includes a `redirectUrls` property
 
 When given an unsupported protocol.
 
+#### got.CancelError
+
+When the request is aborted with `.cancel()`.
+
 
 ## Aborting the request
 
@@ -296,6 +300,22 @@ request.catch(err => {
 request.cancel();
 ```
 
+Or
+
+```js
+const request = got(url, options);
+
+request.catch(err => {
+  if (err instanceof got.CancelError) {
+    // Handle cancelation
+  }
+
+  // Handle other errors
+});
+
+request.cancel();
+```
+
 
 ## Proxies
 


Test patch:
diff --git a/test/cancel.js b/test/cancel.js
index 3ed0fdf..caa2d15 100644
--- a/test/cancel.js
+++ b/test/cancel.js
@@ -85,3 +85,35 @@ test('cancel immediately', async t => {
 	await t.throws(p);
 	await t.notThrows(aborted, 'Request finished instead of aborting.');
 });
+
+test('recover from cancelation using cancelable promise attribute', async t => {
+	// Canceled before connection started
+	const p = got('http://example.com');
+	const recover = p.catch(err => {
+		if (p.canceled) {
+			return;
+		}
+
+		throw err;
+	});
+
+	p.cancel();
+
+	await t.notThrows(recover);
+});
+
+test('recover from cancellation using error instance', async t => {
+	// Canceled before connection started
+	const p = got('http://example.com');
+	const recover = p.catch(err => {
+		if (err instanceof got.CancelError) {
+			return;
+		}
+
+		throw err;
+	});
+
+	p.cancel();
+
+	await t.notThrows(recover);
+});
Repository: sindresorhus/got
Pull request #412 (2017-11-13 08:02:59)

Improve error handling
Resolves the first part of https://github.com/sindresorhus/got/issues/392
Related: https://github.com/sindresorhus/got/pull/384

Now if the request function throws we will emit a `got.RequestError`.


Patch:
diff --git a/index.js b/index.js
index 09ea52a..b70ed1e 100644
--- a/index.js
+++ b/index.js
@@ -198,7 +198,13 @@ function requestAsEventEmitter(opts) {
 			});
 		});
 
-		cacheReq.on('error', err => ee.emit('error', new got.CacheError(err, opts)));
+		cacheReq.on('error', err => {
+			if (err instanceof CacheableRequest.RequestError) {
+				ee.emit('error', new got.RequestError(err, opts));
+			} else {
+				ee.emit('error', new got.CacheError(err, opts));
+			}
+		});
 
 		cacheReq.on('request', req => {
 			req.once('error', err => {
@@ -458,10 +464,17 @@ function normalizeArguments(url, opts) {
 		opts
 	);
 
+	const headers = lowercaseKeys(opts.headers);
+	for (const key of Object.keys(headers)) {
+		if (headers[key] === null || headers[key] === undefined) {
+			delete headers[key];
+		}
+	}
+
 	opts.headers = Object.assign({
 		'user-agent': `${pkg.name}/${pkg.version} (https://github.com/sindresorhus/got)`,
 		'accept-encoding': 'gzip,deflate'
-	}, lowercaseKeys(opts.headers));
+	}, headers);
 
 	const query = opts.query;
 
diff --git a/package.json b/package.json
index 6119377..39aca30 100644
--- a/package.json
+++ b/package.json
@@ -50,7 +50,7 @@
 		"electron"
 	],
 	"dependencies": {
-		"cacheable-request": "^2.0.0",
+		"cacheable-request": "^2.1.0",
 		"decompress-response": "^3.2.0",
 		"duplexer3": "^0.1.4",
 		"get-stream": "^3.0.0",


Test patch:
diff --git a/test/error.js b/test/error.js
index f9a116a..ae05acc 100644
--- a/test/error.js
+++ b/test/error.js
@@ -73,7 +73,8 @@ test.serial('http.request error', async t => {
 		throw new TypeError('The header content contains invalid characters');
 	});
 	const err = await t.throws(got(s.url));
-	t.regex(err.message, /The header content contains invalid characters/);
+	t.true(err instanceof got.RequestError);
+	t.is(err.message, 'The header content contains invalid characters');
 	stub.restore();
 });
 
diff --git a/test/headers.js b/test/headers.js
index 2a0a0ae..07fa774 100644
--- a/test/headers.js
+++ b/test/headers.js
@@ -89,6 +89,24 @@ test('form-data automatic content-type', async t => {
 	t.is(headers['content-type'], `multipart/form-data; boundary=${form.getBoundary()}`);
 });
 
+test('remove null value headers', async t => {
+	const headers = (await got(s.url, {
+		headers: {
+			unicorns: null
+		}
+	})).body;
+	t.false(Object.prototype.hasOwnProperty.call(headers, 'unicorns'));
+});
+
+test('remove undefined value headers', async t => {
+	const headers = (await got(s.url, {
+		headers: {
+			unicorns: undefined
+		}
+	})).body;
+	t.false(Object.prototype.hasOwnProperty.call(headers, 'unicorns'));
+});
+
 test.after('cleanup', async () => {
 	await s.close();
 });
Repository: sindresorhus/got
Pull request #424 (2017-11-22 08:16:43)

Correctly forward stream errors
Related to #388


Patch:
diff --git a/index.js b/index.js
index 7082301..8bf06d5 100644
--- a/index.js
+++ b/index.js
@@ -416,6 +416,10 @@ function asStream(opts) {
 
 		const statusCode = res.statusCode;
 
+		res.on('error', err => {
+			proxy.emit('error', new got.ReadError(err, opts));
+		});
+
 		res.pipe(output);
 
 		if (statusCode !== 304 && (statusCode < 200 || statusCode > 299)) {


Test patch:
diff --git a/test/gzip.js b/test/gzip.js
index 5033509..7b4841b 100644
--- a/test/gzip.js
+++ b/test/gzip.js
@@ -66,6 +66,13 @@ test('handles gzip error', async t => {
 	t.is(err.name, 'ReadError');
 });
 
+test('handles gzip error - stream', async t => {
+	const err = await t.throws(getStream(got.stream(`${s.url}/corrupted`)));
+	t.is(err.message, 'incorrect header check');
+	t.is(err.path, '/corrupted');
+	t.is(err.name, 'ReadError');
+});
+
 test('decompress option opts out of decompressing', async t => {
 	const response = await got(s.url, {decompress: false});
 	t.true(Buffer.compare(response.body, gzipData) === 0);
Repository: sindresorhus/got
Pull request #465 (2018-03-01 08:05:35)

Fix socket 'connect' memory leak
After turning on keep-alive agent with got@8.2.0 i found memory leak. The `connect` listener on a socket is not executed because socket already connected.

Related issue in `request` module: https://github.com/request/request/issues/2438

floatdrop: Lgtm. @sindresorhus can we issue a patch with this fix?

Patch:
diff --git a/index.js b/index.js
index 0d9eb0b..52c613f 100644
--- a/index.js
+++ b/index.js
@@ -227,14 +227,18 @@ function requestAsEventEmitter(opts) {
 					total: uploadBodySize
 				});
 
-				if (req.connection) {
-					req.connection.once('connect', () => {
+				const socket = req.connection;
+				if (socket) {
+					// `._connecting` was the old property which was made public in node v6.1.0
+					const isConnecting = socket.connecting === undefined ? socket._connecting : socket.connecting;
+
+					const onSocketConnect = () => {
 						const uploadEventFrequency = 150;
 
 						progressInterval = setInterval(() => {
 							const lastUploaded = uploaded;
 							const headersSize = Buffer.byteLength(req._header);
-							uploaded = req.connection.bytesWritten - headersSize;
+							uploaded = socket.bytesWritten - headersSize;
 
 							// Prevent the known issue of `bytesWritten` being larger than body size
 							if (uploadBodySize && uploaded > uploadBodySize) {
@@ -254,7 +258,17 @@ function requestAsEventEmitter(opts) {
 								total: uploadBodySize
 							});
 						}, uploadEventFrequency);
-					});
+					};
+
+					// Only subscribe to 'connect' event if we're actually connecting a new
+					// socket, otherwise if we're already connected (because this is a
+					// keep-alive connection) do not bother. This is important since we won't
+					// get a 'connect' event for an already connected socket.
+					if (isConnecting) {
+						socket.once('connect', onSocketConnect);
+					} else {
+						onSocketConnect();
+					}
 				}
 			});
 


Test patch:
diff --git a/test/agent.js b/test/agent.js
index 3ccdc70..062b671 100644
--- a/test/agent.js
+++ b/test/agent.js
@@ -134,10 +134,14 @@ test('redirects from https to http work with an agent object', async t => {
 
 test('socket connect listener cleaned up after request', async t => {
 	const {agent} = createAgentSpy(HttpsAgent);
-	await got(`${https.url}`, {
-		rejectUnauthorized: false,
-		agent
-	});
+	// Make sure there are no memory leaks when reusing keep-alive sockets
+	for (let i = 0; i < 20; i++) {
+		// eslint-disable-next-line no-await-in-loop
+		await got(`${https.url}`, {
+			rejectUnauthorized: false,
+			agent
+		});
+	}
 	Object.keys(agent.freeSockets).forEach(k => agent.freeSockets[k]
 		.forEach(sock => t.is(sock.listenerCount('connect'), 0)));
 	// Make sure to close all open sockets
Repository: sindresorhus/got
Pull request #472 (2018-03-28 13:45:14)

Do not override `Accept-Encoding` header if already provided
It's currently not possible to set the `Accept-Encoding` header to `gzip` only. We would like to do so because we've noticed some servers sending malformed `deflate` responses that Node is not able to inflate.

brandon93s: Whoops! My comment was wrong - shouldn't be negated. 
pietermees: @brandon93s this PR also changes the default value from `gzip,deflate` to `gzip, deflate`. At first I thought the space was required, but it seems that's only specified as such in the Fetch API (see https://fetch.spec.whatwg.org/#concept-header-value-combined) while the HTTP spec says that a simple `,` is fine. I thought it might make sense to align closer to fetch moving forward?

Patch:
diff --git a/index.js b/index.js
index 2ca8862..7a5d4c0 100644
--- a/index.js
+++ b/index.js
@@ -527,8 +527,8 @@ function normalizeArguments(url, opts) {
 		'user-agent': `${pkg.name}/${pkg.version} (https://github.com/sindresorhus/got)`
 	}, headers);
 
-	if (opts.decompress) {
-		opts.headers['accept-encoding'] = 'gzip,deflate';
+	if (opts.decompress && is.undefined(opts.headers['accept-encoding'])) {
+		opts.headers['accept-encoding'] = 'gzip, deflate';
 	}
 
 	const query = opts.query;
diff --git a/readme.md b/readme.md
index 1691276..11ed89c 100644
--- a/readme.md
+++ b/readme.md
@@ -195,7 +195,7 @@ request the resource pointed to in the location header via `GET`. This is in acc
 Type: `boolean`<br>
 Default: `true`
 
-Decompress the response automatically.
+Decompress the response automatically. This will set the `accept-encoding` header to `gzip, deflate` unless you set it yourself.
 
 If this is disabled, a compressed response is returned as a `Buffer`. This may be useful if you want to handle decompression yourself or stream the raw compressed data.
 


Test patch:
diff --git a/test/headers.js b/test/headers.js
index ba07cf5..ed7c056 100644
--- a/test/headers.js
+++ b/test/headers.js
@@ -24,7 +24,17 @@ test('user-agent', async t => {
 
 test('accept-encoding', async t => {
 	const headers = (await got(s.url, {json: true})).body;
-	t.is(headers['accept-encoding'], 'gzip,deflate');
+	t.is(headers['accept-encoding'], 'gzip, deflate');
+});
+
+test('do not override accept-encoding', async t => {
+	const headers = (await got(s.url, {
+		json: true,
+		headers: {
+			'accept-encoding': 'gzip'
+		}
+	})).body;
+	t.is(headers['accept-encoding'], 'gzip');
 });
 
 test('do not set accept-encoding header when decompress options is false', async t => {
Repository: sindresorhus/got
Pull request #499 (2018-07-05 18:03:09)

Fix merging defaults and options
Fixes commit 058452b.

sindresorhus: Sorry, I moved the source files into a `source` directory earlier... Could you update the PR?

Patch:
diff --git a/source/index.js b/source/index.js
index d6e2b83..197129d 100644
--- a/source/index.js
+++ b/source/index.js
@@ -98,7 +98,7 @@ function requestAsEventEmitter(options = {}) {
 		}
 
 		if (options.useElectronNet && process.versions.electron) {
-			const electron = require('electron');
+			const electron = global['require']('electron'); // eslint-disable-line dot-notation
 			fn = electron.net || electron.remote.net;
 		}
 
@@ -541,15 +541,6 @@ function normalizeArguments(url, options) {
 		...options
 	};
 
-	for (const [key, value] of Object.entries(options.headers)) {
-		if (is.nullOrUndefined(value)) {
-			delete options.headers[key];
-			continue;
-		}
-
-		options.headers[key.toLowerCase()] = value;
-	}
-
 	if (options.decompress && is.undefined(options.headers['accept-encoding'])) {
 		options.headers['accept-encoding'] = 'gzip, deflate';
 	}
@@ -654,10 +645,25 @@ function normalizeArguments(url, options) {
 	return options;
 }
 
+function assignOptions(defaults, options = {}) {
+	const opts = extend(true, {}, defaults, options);
+
+	if (Reflect.has(options, 'headers')) {
+		for (const [key, value] of Object.entries(options.headers)) {
+			if (is.nullOrUndefined(value)) {
+				delete opts.headers[key];
+				continue;
+			}
+		}
+	}
+
+	return opts;
+}
+
 function create(defaults = {}) {
 	function got(url, options) {
 		try {
-			options = extend(true, {}, defaults, options);
+			options = assignOptions(defaults, options);
 			const normalizedArgs = normalizeArguments(url, options);
 
 			if (normalizedArgs.stream) {
@@ -670,10 +676,10 @@ function create(defaults = {}) {
 		}
 	}
 
-	got.create = (options = {}) => create(extend(true, {}, defaults, options));
+	got.create = (options = {}) => create(assignOptions(defaults, options));
 
 	got.stream = (url, options) => {
-		options = extend(true, {}, defaults, options);
+		options = assignOptions(defaults, options);
 		return asStream(normalizeArguments(url, options));
 	};
 


Test patch:
diff --git a/test/headers.js b/test/headers.js
index 4b99f58..687b8c6 100644
--- a/test/headers.js
+++ b/test/headers.js
@@ -135,7 +135,7 @@ test('remove null value headers', async t => {
 	t.false(Reflect.has(headers, 'user-agent'));
 });
 
-test.failing('remove undefined value headers', async t => {
+test('remove undefined value headers', async t => {
 	const {body} = await got(s.url, {
 		headers: {
 			'user-agent': undefined
Repository: sindresorhus/got
Pull request #550 (2018-08-09 10:56:03)

Fix throwing errors when using got.stream()
If normalizing arguments throws and using `got.stream()`, it'd return a rejecting promise. This PR fixes that.


Patch:
diff --git a/source/create.js b/source/create.js
index c7023e6..64665a0 100644
--- a/source/create.js
+++ b/source/create.js
@@ -20,7 +20,11 @@ const create = defaults => {
 			options = mergeOptions(defaults.options, options);
 			return defaults.handler(normalizeArguments(url, options, defaults), next);
 		} catch (error) {
-			return Promise.reject(error);
+			if (options.stream) {
+				throw error;
+			} else {
+				return Promise.reject(error);
+			}
 		}
 	}
 


Test patch:
diff --git a/test/error.js b/test/error.js
index b1b8239..f7d5af2 100644
--- a/test/error.js
+++ b/test/error.js
@@ -133,3 +133,9 @@ test.serial('catch error in mimicResponse', async t => {
 
 	await t.throws(proxiedGot(s.url), {message: 'Error in mimic-response'});
 });
+
+test('errors are thrown directly when options.stream is true', t => {
+	t.throws(() => got(s.url, {stream: true, body: {}}), {
+		message: 'The `body` option must be a stream.Readable, string or Buffer'
+	});
+});
Repository: sindresorhus/got
Pull request #578 (2018-08-23 08:32:27)

Bump `get-stream` to 0.4.0


Patch:
diff --git a/package.json b/package.json
index d98239e..89dd886 100644
--- a/package.json
+++ b/package.json
@@ -38,7 +38,7 @@
 		"cacheable-request": "^4.0.1",
 		"decompress-response": "^3.3.0",
 		"duplexer3": "^0.1.4",
-		"get-stream": "^3.0.0",
+		"get-stream": "^4.0.0",
 		"mimic-response": "^1.0.0",
 		"p-cancelable": "^0.5.0",
 		"to-readable-stream": "^1.0.0",
diff --git a/source/deep-freeze.js b/source/deep-freeze.js
index b4ded11..5052b71 100644
--- a/source/deep-freeze.js
+++ b/source/deep-freeze.js
@@ -3,7 +3,7 @@ const is = require('@sindresorhus/is');
 
 module.exports = function deepFreeze(object) {
 	for (const [key, value] of Object.entries(object)) {
-		if (is.object(value)) {
+		if (is.plainObject(value) || is.array(value)) {
 			deepFreeze(object[key]);
 		}
 	}


Test patch:
diff --git a/test/cancel.js b/test/cancel.js
index a33d753..b014210 100644
--- a/test/cancel.js
+++ b/test/cancel.js
@@ -1,7 +1,7 @@
 import EventEmitter from 'events';
 import {Readable} from 'stream';
 import test from 'ava';
-import getStream from 'get-stream';
+import pEvent from 'p-event';
 import PCancelable from 'p-cancelable';
 import got from '../source';
 import {createServer} from './helpers/server';
@@ -15,7 +15,7 @@ async function createAbortServer() {
 			request.on('aborted', resolve);
 			response.on('finish', reject.bind(null, new Error('Request finished instead of aborting.')));
 
-			await getStream(request);
+			await pEvent(request, 'end');
 			response.end();
 		});
 
diff --git a/test/create.js b/test/create.js
index ddafa80..4e688b8 100644
--- a/test/create.js
+++ b/test/create.js
@@ -1,3 +1,4 @@
+import http from 'http';
 import {URL} from 'url';
 import test from 'ava';
 import got from '../source';
@@ -145,6 +146,14 @@ test('no tampering with defaults', t => {
 	t.is(instance2.defaults.options.baseUrl, 'example');
 });
 
+test('only plain objects are freezed', async t => {
+	const instance = got.extend({
+		agent: new http.Agent({keepAlive: true})
+	});
+
+	await t.notThrowsAsync(() => instance(s.url));
+});
+
 test('defaults are cloned on instance creation', t => {
 	const options = {foo: 'bar', hooks: {beforeRequest: [() => {}]}};
 	const instance = got.create({options});