Skip to content

gcp-resources: add connect and read timeout, add response body limit#2883

Open
jack-berg wants to merge 1 commit into
open-telemetry:mainfrom
jack-berg:gcp-metadata-timeout-limit
Open

gcp-resources: add connect and read timeout, add response body limit#2883
jack-berg wants to merge 1 commit into
open-telemetry:mainfrom
jack-berg:gcp-metadata-timeout-limit

Conversation

@jack-berg

Copy link
Copy Markdown
Member

No description provided.

Copilot AI review requested due to automatic review settings May 28, 2026 20:40
@jack-berg jack-berg requested a review from a team as a code owner May 28, 2026 20:40
@github-actions github-actions Bot requested review from jsuereth and psx95 May 28, 2026 20:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds explicit connect and read timeouts to the GCP metadata HTTP fetch and bounds the response body size read from the metadata server to 4096 characters, replacing the prior BufferedReader.readLine() call with a fixed-size character read.

Changes:

  • Introduce CONNECT_TIMEOUT_MS (1s) and READ_TIMEOUT_MS (1s) constants and apply them to the HttpURLConnection.
  • Cap metadata response reads at MAX_METADATA_VALUE_CHARS (4096) via a single Reader.read into a char buffer.
  • Add a unit test asserting an oversized metadata body is truncated to 4096 characters.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
gcp-resources/src/main/java/io/opentelemetry/contrib/gcp/resource/GcpMetadataConfig.java Adds connect/read timeouts and replaces line-based read with bounded char-buffer read.
gcp-resources/src/test/java/io/opentelemetry/contrib/gcp/resource/GcpMetadataConfigTest.java Adds test verifying 8192-char response is truncated to 4096 chars.

Comment on lines +163 to +165
char[] buffer = new char[MAX_METADATA_VALUE_CHARS];
int n = reader.read(buffer, 0, buffer.length);
return n > 0 ? new String(buffer, 0, n) : null;
Comment on lines +164 to +165
int n = reader.read(buffer, 0, buffer.length);
return n > 0 ? new String(buffer, 0, n) : null;

@psx95 psx95 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @jack-berg ,
Thanks for the PR, adding a connect and read timeout makes sense. I'm just wondering if something specific prompted this change.

return n > 0 ? new String(buffer, 0, n) : null;
}
}
} catch (IOException ignore) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When adding the read connect timeouts, I think the catch block should explicitly check for SocketTimeoutException and log a warning.

Might be better to place the connection.getResponseCode() and connection.getInputStream() in individual try catch blocks to explicitly log if it was a read timeout or connect timeout.

I'm hoping if this becomes a frequent issue, the users can inform us about the exact cause.

try (BufferedReader reader =
new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8))) {
return reader.readLine();
char[] buffer = new char[MAX_METADATA_VALUE_CHARS];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this required. Would readLine really be that inefficient?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all about limiting the size of the payload read into memory in the event the server is malicious. I don't think readLine would impose any limits if there's a huge payload all on one line.

Its unlikely, since we're connecting to google servers, but its just a bit more cautious. (I don't think there's technically anything that guarantees that the server at http://metadata.google.internal/computeMetadata/v1/ is googles in the case that the network / DNS has been compromised.

Comment on lines +33 to +34
private static final int CONNECT_TIMEOUT_MS = 1_000;
private static final int READ_TIMEOUT_MS = 1_000;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I think these timeouts make sense (since we are only doing simple gets), I am wondering if it would be better to expose them as optional configuration.

static final GcpMetadataConfig DEFAULT_INSTANCE = new GcpMetadataConfig();

private static final String DEFAULT_URL = "http://metadata.google.internal/computeMetadata/v1/";
// google-auth-library-java uses 500 ms connect timeout (with up to 3 retries) for its metadata

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Why does auth-library matter here? It does not seem to be a dependency of this component.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its a reference for another library that interacts with these same APIs to inform the decisions here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants