fix: Don't sort the headers of ClientRequest (#26134)
This commit is contained in:
parent
2d1bbd2e38
commit
0fc5f18b63
3 changed files with 53 additions and 1 deletions
|
@ -378,7 +378,7 @@ gin::Handle<SimpleURLLoaderWrapper> SimpleURLLoaderWrapper::Create(
|
||||||
opts.Get("referrer", &request->referrer);
|
opts.Get("referrer", &request->referrer);
|
||||||
bool credentials_specified =
|
bool credentials_specified =
|
||||||
opts.Get("credentials", &request->credentials_mode);
|
opts.Get("credentials", &request->credentials_mode);
|
||||||
std::map<std::string, std::string> extra_headers;
|
std::vector<std::pair<std::string, std::string>> extra_headers;
|
||||||
if (opts.Get("extraHeaders", &extra_headers)) {
|
if (opts.Get("extraHeaders", &extra_headers)) {
|
||||||
for (const auto& it : extra_headers) {
|
for (const auto& it : extra_headers) {
|
||||||
if (!net::HttpUtil::IsValidHeaderName(it.first) ||
|
if (!net::HttpUtil::IsValidHeaderName(it.first) ||
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#define SHELL_COMMON_GIN_CONVERTERS_NET_CONVERTER_H_
|
#define SHELL_COMMON_GIN_CONVERTERS_NET_CONVERTER_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "gin/converter.h"
|
#include "gin/converter.h"
|
||||||
#include "services/network/public/mojom/fetch_api.mojom.h"
|
#include "services/network/public/mojom/fetch_api.mojom.h"
|
||||||
|
@ -112,6 +114,35 @@ struct Converter<net::RedirectInfo> {
|
||||||
const net::RedirectInfo& val);
|
const net::RedirectInfo& val);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename K, typename V>
|
||||||
|
struct Converter<std::vector<std::pair<K, V>>> {
|
||||||
|
static bool FromV8(v8::Isolate* isolate,
|
||||||
|
v8::Local<v8::Value> value,
|
||||||
|
std::vector<std::pair<K, V>>* out) {
|
||||||
|
if (!value->IsObject())
|
||||||
|
return false;
|
||||||
|
out->clear();
|
||||||
|
v8::Local<v8::Context> context = isolate->GetCurrentContext();
|
||||||
|
v8::Local<v8::Object> obj = value.As<v8::Object>();
|
||||||
|
v8::Local<v8::Array> keys = obj->GetPropertyNames(context).ToLocalChecked();
|
||||||
|
for (uint32_t i = 0; i < keys->Length(); ++i) {
|
||||||
|
v8::Local<v8::Value> v8key;
|
||||||
|
if (!keys->Get(context, i).ToLocal(&v8key))
|
||||||
|
return false;
|
||||||
|
v8::Local<v8::Value> v8value;
|
||||||
|
if (!obj->Get(context, v8key).ToLocal(&v8value))
|
||||||
|
return false;
|
||||||
|
K key;
|
||||||
|
V value;
|
||||||
|
if (!ConvertFromV8(isolate, v8key, &key) ||
|
||||||
|
!ConvertFromV8(isolate, v8value, &value))
|
||||||
|
return false;
|
||||||
|
(*out).emplace_back(std::move(key), std::move(value));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace gin
|
} // namespace gin
|
||||||
|
|
||||||
#endif // SHELL_COMMON_GIN_CONVERTERS_NET_CONVERTER_H_
|
#endif // SHELL_COMMON_GIN_CONVERTERS_NET_CONVERTER_H_
|
||||||
|
|
|
@ -537,6 +537,27 @@ describe('net module', () => {
|
||||||
await collectStreamBody(response);
|
await collectStreamBody(response);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should keep the order of headers', async () => {
|
||||||
|
const customHeaderNameA = 'X-Header-100';
|
||||||
|
const customHeaderNameB = 'X-Header-200';
|
||||||
|
const serverUrl = await respondOnce.toSingleURL((request, response) => {
|
||||||
|
const headerNames = Array.from(Object.keys(request.headers));
|
||||||
|
const headerAIndex = headerNames.indexOf(customHeaderNameA.toLowerCase());
|
||||||
|
const headerBIndex = headerNames.indexOf(customHeaderNameB.toLowerCase());
|
||||||
|
expect(headerBIndex).to.be.below(headerAIndex);
|
||||||
|
response.statusCode = 200;
|
||||||
|
response.statusMessage = 'OK';
|
||||||
|
response.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
const urlRequest = net.request(serverUrl);
|
||||||
|
urlRequest.setHeader(customHeaderNameB, 'b');
|
||||||
|
urlRequest.setHeader(customHeaderNameA, 'a');
|
||||||
|
const response = await getResponse(urlRequest);
|
||||||
|
expect(response.statusCode).to.equal(200);
|
||||||
|
await collectStreamBody(response);
|
||||||
|
});
|
||||||
|
|
||||||
it('should be able to set cookie header line', async () => {
|
it('should be able to set cookie header line', async () => {
|
||||||
const cookieHeaderName = 'Cookie';
|
const cookieHeaderName = 'Cookie';
|
||||||
const cookieHeaderValue = 'test=12345';
|
const cookieHeaderValue = 'test=12345';
|
||||||
|
|
Loading…
Reference in a new issue