Repository: node-fetch/node-fetch (js)

Issue:
non-standard HTTP methods are not uppercased by Chrome
<!--- Provide a clear and concise description of what the bug is. -->

**Reproduction**

Steps to reproduce the behavior:
In the browser (Google Chrome), run this code from the console then look at the request in the Dev Tools Network tab

```js
fetch('aoeu.jpg', {method: 'weirdMETHOD'})
```

It'll show

```
Request Method: weirdMETHOD
```

but 
```
fetch('aoeu.jpg', {method: 'post'})
```

will send `POST`.

But if you run the same code with `node-fetch`, it'll send `WEIRDMETHOD`

```js
import fetch from 'node-fetch';
fetch('http://localhost:8888/', {method: 'weirdMETHOD'});
```
```
nc -kl 8888
```

will show

```
WEIRDMETHOD / HTTP/1.1
```

**Expected behavior**

`node-fetch` will behave the same way as Chrome's `fetch()`

**Your Environment**

<!--- Include as many relevant details about the environment you experienced the bug in -->

| software         | version
| ---------------- | -------
| node-fetch       | ^3.2.3
| node             |v16.14.2
| npm              |8.5.3
| Operating System |macOS 12.3.1

Pull request:
fix: don't uppercase unknown methods
<!-- Thanks for contributing! -->

## Purpose
The purpose is to follow [Fetch Spec](https://fetch.spec.whatwg.org/#concept-method-normalize) 

## Changes

As per spec:
To normalize a method, if it is a byte-case-insensitive match for `DELETE`, `GET`, `HEAD`, `OPTIONS`, `POST`, or `PUT`, byte-uppercase it. 

___

<!-- Mark the ones you have done and remove unnecessary ones. Add new tasks that fit (like TODOs). -->
- [ ] I updated readme
- [ ] I added unit test(s)

___

<!-- Add `- fix #_NUMBER_` line for every PR/Issue this PR solves. Do not comma separate them. -->
- fix #1538


Patch:
diff --git a/src/request.js b/src/request.js
index a4d1b22..a63f7e6 100644
--- a/src/request.js
+++ b/src/request.js
@@ -61,7 +61,9 @@ export default class Request extends Body {
 		}
 
 		let method = init.method || input.method || 'GET';
-		method = method.toUpperCase();
+		if (/^(delete|get|head|options|post|put)$/i.test(method)) {
+			method = method.toUpperCase();
+		}
 
 		if ('data' in init) {
 			doBadDataWarn();


Test patch:
diff --git a/test/request.js b/test/request.js
index b8ba107..03cbe3c 100644
--- a/test/request.js
+++ b/test/request.js
@@ -151,6 +151,24 @@ describe('Request', () => {
 		expect(request.headers.get('a')).to.equal('1');
 	});
 
+	it('should uppercase DELETE, GET, HEAD, OPTIONS, POST and PUT methods', () => {
+		const url = base;
+		for (const method of ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']) {
+			const request = new Request(url, {
+				method: method.toLowerCase()
+			});
+			expect(request.method).to.equal(method);
+		}
+	});
+
+	it('should not uppercase unknown methods and patch', () => {
+		const url = base;
+		for (const method of ['patch', 'chicken']) {
+			const request = new Request(url, {method});
+			expect(request.method).to.equal(method);
+		}
+	});
+
 	it('should support arrayBuffer() method', () => {
 		const url = base;
 		const request = new Request(url, {