mirror of
https://github.com/tenrok/axios.git
synced 2026-06-14 18:42:33 +03:00
fix(http2): fix possible race condition when handling http2 stream on almost timed out session by improving timeout out algorithm; (#7186)
This commit is contained in:
+46
-10
@@ -87,7 +87,15 @@ class Http2Sessions {
|
||||
|
||||
const session = connect(authority, options);
|
||||
|
||||
session.once('close', () => {
|
||||
let removed;
|
||||
|
||||
const removeSession = () => {
|
||||
if (removed) {
|
||||
return;
|
||||
}
|
||||
|
||||
removed = true;
|
||||
|
||||
let entries = authoritySessions, len = entries.length, i = len;
|
||||
|
||||
while (i--) {
|
||||
@@ -99,9 +107,41 @@ class Http2Sessions {
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Http2Sessions.setTimeout(session, options.sessionTimeout);
|
||||
const originalRequestFn = session.request;
|
||||
|
||||
const {sessionTimeout} = options;
|
||||
|
||||
if(sessionTimeout != null) {
|
||||
|
||||
let timer;
|
||||
let streamsCount = 0;
|
||||
|
||||
session.request = function () {
|
||||
const stream = originalRequestFn.apply(this, arguments);
|
||||
|
||||
streamsCount++;
|
||||
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
|
||||
stream.once('close', () => {
|
||||
if (!--streamsCount) {
|
||||
timer = setTimeout(() => {
|
||||
timer = null;
|
||||
removeSession();
|
||||
}, sessionTimeout);
|
||||
}
|
||||
});
|
||||
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
|
||||
session.once('close', removeSession);
|
||||
|
||||
let entries = this.sessions[authority], entry = [
|
||||
session,
|
||||
@@ -112,12 +152,6 @@ class Http2Sessions {
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
static setTimeout(session, timeout = 1000) {
|
||||
session && session.setTimeout(timeout, () => {
|
||||
session.close();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const http2Sessions = new Http2Sessions();
|
||||
@@ -284,10 +318,12 @@ export default isHttpAdapterSupported && function httpAdapter(config) {
|
||||
let rejected = false;
|
||||
let req;
|
||||
|
||||
httpVersion = Number(httpVersion);
|
||||
httpVersion = +httpVersion;
|
||||
|
||||
if (Number.isNaN(httpVersion)) {
|
||||
throw TypeError(`Invalid protocol version: '${config.httpVersion}' is not a number`);
|
||||
}
|
||||
|
||||
if (httpVersion !== 1 && httpVersion !== 2) {
|
||||
throw TypeError(`Unsupported protocol version '${httpVersion}'`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user