Repository: axios/axios (js)

Issue:
Error: header name must be a non-empty string
### Describe the bug

Error: `header name must be a non-empty string` is thrown we coping empty headers object

I suspect [set method ](https://github.com/axios/axios/blob/5a9134e0995b08cc0817548ed44e79c420c620b7/lib/core/AxiosHeaders.js#L82) of AxiosHeaders do not detect instance properly

Given a code
```typescript
import {AxiosHeaders} from "axios";
const axios = require('axios');

new AxiosHeaders(new axios.AxiosHeaders());
```
Expected: empty headers created
Actual: `header name must be a non-empty string` error thrown

### To Reproduce

Please run the code below to reproduce, I tested on 1.8.x and 1.7.x versions

### Code snippet

```js
import {AxiosHeaders} from "axios";
const axios = require('axios');

new AxiosHeaders(new axios.AxiosHeaders());
```

Run the code
```
esbuild reproduce.ts --bundle --platform=node | node
```

### Expected behavior

an empty headers object created
### Actual behavior

```
Error: header name must be a non-empty string
    at setHeader ([stdin]:15089:15)
    at AxiosHeaders.set ([stdin]:15106:25)
    at new AxiosHeaders ([stdin]:15082:21)
    at [stdin]:17352:1
    at runScriptInThisContext (node:internal/vm:209:10)
    at node:internal/process/execution:118:14
    at [stdin]-wrapper:6:24
    at runScript (node:internal/process/execution:101:62)
    at evalScript (node:internal/process/execution:133:3)
    at node:internal/main/eval_stdin:32:5

Node.js v20.17.0
```


### Axios Version

1.8.3

### Adapter Version

_No response_

### Browser

_No response_

### Browser Version

_No response_

### Node.js Version

20.x

### OS

OSx 15.3.2

### Additional Library Versions

```bash

```

### Additional context/Screenshots

```bash

```

Pull request:
fix(headers): allow iterable objects to be a data source for the set method;
Fixes #6856;

Patch:
diff --git a/lib/core/AxiosHeaders.js b/lib/core/AxiosHeaders.js
index 2212f77..fd996a3 100644
--- a/lib/core/AxiosHeaders.js
+++ b/lib/core/AxiosHeaders.js
@@ -100,9 +100,12 @@ class AxiosHeaders {
       setHeaders(header, valueOrRewrite)
     } else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
       setHeaders(parseHeaders(header), valueOrRewrite);
-    } else if (utils.isHeaders(header)) {
-      for (const [key, value] of header.entries()) {
-        setHeader(value, key, rewrite);
+    } else if (utils.isObject(header) && utils.isIterable(header)) {
+      for (const entry of header) {
+        if (!utils.isArray(entry)) {
+          throw TypeError('Object iterator must return a key-value pair');
+        }
+        setHeader(entry[1], entry[0], rewrite);
       }
     } else {
       header != null && setHeader(valueOrRewrite, header, rewrite);
diff --git a/lib/utils.js b/lib/utils.js
index c48eb1e..a5ed039 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -6,6 +6,7 @@ import bind from './helpers/bind.js';
 
 const {toString} = Object.prototype;
 const {getPrototypeOf} = Object;
+const {iterator, toStringTag} = Symbol;
 
 const kindOf = (cache => thing => {
     const str = toString.call(thing);
@@ -132,7 +133,7 @@ const isPlainObject = (val) => {
   }
 
   const prototype = getPrototypeOf(val);
-  return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(Symbol.toStringTag in val) && !(Symbol.iterator in val);
+  return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val);
 }
 
 /**
@@ -483,13 +484,13 @@ const isTypedArray = (TypedArray => {
  * @returns {void}
  */
 const forEachEntry = (obj, fn) => {
-  const generator = obj && obj[Symbol.iterator];
+  const generator = obj && obj[iterator];
 
-  const iterator = generator.call(obj);
+  const _iterator = generator.call(obj);
 
   let result;
 
-  while ((result = iterator.next()) && !result.done) {
+  while ((result = _iterator.next()) && !result.done) {
     const pair = result.value;
     fn.call(obj, pair[0], pair[1]);
   }
@@ -610,7 +611,7 @@ const toFiniteNumber = (value, defaultValue) => {
  * @returns {boolean}
  */
 function isSpecCompliantForm(thing) {
-  return !!(thing && isFunction(thing.append) && thing[Symbol.toStringTag] === 'FormData' && thing[Symbol.iterator]);
+  return !!(thing && isFunction(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]);
 }
 
 const toJSONObject = (obj) => {
@@ -679,6 +680,10 @@ const asap = typeof queueMicrotask !== 'undefined' ?
 
 // *********************
 
+
+const isIterable = (thing) => thing != null && isFunction(thing[iterator]);
+
+
 export default {
   isArray,
   isArrayBuffer,
@@ -734,5 +739,6 @@ export default {
   isAsyncFn,
   isThenable,
   setImmediate: _setImmediate,
-  asap
+  asap,
+  isIterable
 };


Test patch:
diff --git a/test/unit/core/AxiosHeaders.js b/test/unit/core/AxiosHeaders.js
index e4e577b..0c5258c 100644
--- a/test/unit/core/AxiosHeaders.js
+++ b/test/unit/core/AxiosHeaders.js
@@ -73,7 +73,15 @@ describe('AxiosHeaders', function () {
       headers.set('foo', 'value2', true);
 
       assert.strictEqual(headers.get('foo'), 'value2');
-    })
+    });
+
+    it('should support iterables as a key-value source object', function () {
+      const headers = new AxiosHeaders();
+
+      headers.set(new Map([['x', '123']]));
+
+      assert.strictEqual(headers.get('x'), '123');
+    });
   });
 
   it('should support uppercase name mapping for names overlapped by class methods', () => {