mirror of
https://github.com/coder/coder.git
synced 2026-09-22 13:10:21 +08:00
chore: record and raise problematic http protocols for each proxy (#15917)
Adds warnings to the proxy and proxy health pages on HTTP 1.1, 1.0, 0.9 protocols. Only the performance API can return the HTTP protocol type. We already use the performance API for latency timings, and each proxy could have this issue.
This commit is contained in:
@@ -15,6 +15,11 @@ export interface ProxyLatencyReport {
|
||||
latencyMS: number;
|
||||
// at is when the latency was recorded.
|
||||
at: Date;
|
||||
/**
|
||||
* nextHopProtocol can determine if HTTP/2 is being used.
|
||||
* https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/nextHopProtocol
|
||||
*/
|
||||
nextHopProtocol?: string;
|
||||
}
|
||||
|
||||
interface ProxyLatencyAction {
|
||||
@@ -151,6 +156,7 @@ export const useProxyLatency = (
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/Resource_timing
|
||||
let latencyMS = 0;
|
||||
let accurate = false;
|
||||
let nextHopProtocol: string | undefined = undefined;
|
||||
if (
|
||||
"requestStart" in entry &&
|
||||
(entry as PerformanceResourceTiming).requestStart !== 0
|
||||
@@ -159,6 +165,7 @@ export const useProxyLatency = (
|
||||
const timingEntry = entry as PerformanceResourceTiming;
|
||||
latencyMS = timingEntry.responseStart - timingEntry.requestStart;
|
||||
accurate = true;
|
||||
nextHopProtocol = timingEntry.nextHopProtocol;
|
||||
} else {
|
||||
// This is the total duration of the request and will be off by a good margin.
|
||||
// This is a fallback if the better timing is not available.
|
||||
@@ -175,7 +182,8 @@ export const useProxyLatency = (
|
||||
latencyMS,
|
||||
accurate,
|
||||
at: new Date(),
|
||||
},
|
||||
nextHopProtocol: nextHopProtocol,
|
||||
} as ProxyLatencyReport,
|
||||
};
|
||||
dispatchProxyLatencies(update);
|
||||
// Also save to local storage to persist the latency across page refreshes.
|
||||
|
||||
@@ -26,12 +26,30 @@ export const ProxyRow: FC<ProxyRowProps> = ({ proxy, latency }) => {
|
||||
// All users can see healthy/unhealthy, some can see more.
|
||||
let statusBadge = <ProxyStatus proxy={proxy} />;
|
||||
let shouldShowMessages = false;
|
||||
const extraWarnings: string[] = [];
|
||||
if (latency?.nextHopProtocol) {
|
||||
switch (latency.nextHopProtocol) {
|
||||
case "http/0.9":
|
||||
case "http/1.0":
|
||||
case "http/1.1":
|
||||
extraWarnings.push(
|
||||
// biome-ignore lint/style/useTemplate: easier to read short lines
|
||||
`Requests to the proxy from current browser are using "${latency.nextHopProtocol}". ` +
|
||||
"The proxy server might not support HTTP/2. " +
|
||||
"For usability reasons, HTTP/2 or above is recommended. " +
|
||||
"Pages may fail to load if the web browser's concurrent " +
|
||||
"connection limit per host is reached.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ("status" in proxy) {
|
||||
const wsproxy = proxy as WorkspaceProxy;
|
||||
statusBadge = <DetailedProxyStatus proxy={wsproxy} />;
|
||||
shouldShowMessages = Boolean(
|
||||
(wsproxy.status?.report?.warnings &&
|
||||
wsproxy.status?.report?.warnings.length > 0) ||
|
||||
extraWarnings.length > 0 ||
|
||||
(wsproxy.status?.report?.errors &&
|
||||
wsproxy.status?.report?.errors.length > 0),
|
||||
);
|
||||
@@ -76,7 +94,10 @@ export const ProxyRow: FC<ProxyRowProps> = ({ proxy, latency }) => {
|
||||
colSpan={4}
|
||||
css={{ padding: "0 !important", borderBottom: 0 }}
|
||||
>
|
||||
<ProxyMessagesRow proxy={proxy as WorkspaceProxy} />
|
||||
<ProxyMessagesRow
|
||||
proxy={proxy as WorkspaceProxy}
|
||||
extraWarnings={extraWarnings}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
@@ -86,9 +107,13 @@ export const ProxyRow: FC<ProxyRowProps> = ({ proxy, latency }) => {
|
||||
|
||||
interface ProxyMessagesRowProps {
|
||||
proxy: WorkspaceProxy;
|
||||
extraWarnings: string[];
|
||||
}
|
||||
|
||||
const ProxyMessagesRow: FC<ProxyMessagesRowProps> = ({ proxy }) => {
|
||||
const ProxyMessagesRow: FC<ProxyMessagesRowProps> = ({
|
||||
proxy,
|
||||
extraWarnings,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
@@ -101,7 +126,7 @@ const ProxyMessagesRow: FC<ProxyMessagesRowProps> = ({ proxy }) => {
|
||||
title={
|
||||
<span css={{ color: theme.palette.warning.light }}>Warnings</span>
|
||||
}
|
||||
messages={proxy.status?.report?.warnings}
|
||||
messages={[...(proxy.status?.report?.warnings ?? []), ...extraWarnings]}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -206,6 +206,10 @@ export const MockProxyLatencies: Record<string, ProxyLatencyReport> = {
|
||||
100) %
|
||||
250,
|
||||
at: new Date(),
|
||||
nextHopProtocol:
|
||||
proxy.id === "8444931c-0247-4171-842a-569d9f9cbadb"
|
||||
? "http/1.1"
|
||||
: "h2",
|
||||
};
|
||||
return acc;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user