Skip to content

Add registrar id header to proxy requests#2791

Merged
ptkach merged 1 commit into
google:masterfrom
ptkach:proxyRegistrarId
Aug 5, 2025
Merged

Add registrar id header to proxy requests#2791
ptkach merged 1 commit into
google:masterfrom
ptkach:proxyRegistrarId

Conversation

@ptkach

@ptkach ptkach commented Aug 4, 2025

Copy link
Copy Markdown
Collaborator

Tested in crash, works as expected


This change is Reviewable

@ptkach
ptkach requested a review from weiminyu August 4, 2025 22:35

@weiminyu weiminyu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewable status: 0 of 3 files reviewed, 1 unresolved discussion


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 164 at r1 (raw file):

  }

  private Optional<String> extractRegistrarIdFromSessionInfo(String sessionInfo) {

Add a few tests?

Code quote:

extractRegistrarIdFromSessionInfo

@CydeWeys CydeWeys left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewable status: 0 of 3 files reviewed, 6 unresolved discussions (waiting on @ptkach and @weiminyu)


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 139 at r1 (raw file):

        .set(HttpHeaderNames.ACCEPT, EPP_CONTENT_TYPE);

    if (maybeRegistrarId.isPresent()

How is this checking if something is present that hasn't even been assigned yet? It's being reused from a previous request in this same connection, or what?


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 171 at r1 (raw file):

    try {
      String decodedString = new String(BaseEncoding.base64Url().decode(sessionInfo), US_ASCII);
      Pattern pattern = Pattern.compile("clientId=([^,\\s]+)?");

Make this compiled pattern a static final on the class, so it doesn't need to be compiled from scratch during each request.


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 178 at r1 (raw file):

        if (!maybeRegistrarIdMatch.equals("null")) {
          maybeRegistrarId = Optional.of(maybeRegistrarIdMatch);
          return maybeRegistrarId;

It's a little confusing that this helper method is both setting an instance variable, and returning that value. (And even worse, that the value is being extracted and set during a conditional check, which typically you wouldn't think would modify any state.) I'd suggest doing one or the other, not both.


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 182 at r1 (raw file):

      }

    } catch (Throwable e) {

This seems like a pretty broad catch, when all you really need to catch seems to be IllegalArgumentException thrown by BaseEncoding.decode()? Are there other exceptions at play here?


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 183 at r1 (raw file):

    } catch (Throwable e) {
      logger.atSevere().withCause(e).log("Failed to decode Base64 string %s", sessionInfo);

How about "Failed to decode session info from Base64"

And should we be logging the session info? Might that not put sensitive data in the logs that shouldn't be there?

@CydeWeys CydeWeys left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewable status: 0 of 3 files reviewed, 7 unresolved discussions (waiting on @ptkach and @weiminyu)


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 165 at r1 (raw file):

  private Optional<String> extractRegistrarIdFromSessionInfo(String sessionInfo) {
    if (sessionInfo == null) {

Annotate sessionInfo above with @Nullable if null is an expected value for it.

@ptkach
ptkach force-pushed the proxyRegistrarId branch from 411719e to 2509b1a Compare August 5, 2025 16:11

@ptkach ptkach left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Reviewable status: 0 of 4 files reviewed, 7 unresolved discussions (waiting on @CydeWeys and @weiminyu)


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 139 at r1 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

How is this checking if something is present that hasn't even been assigned yet? It's being reused from a previous request in this same connection, or what?

The instance is alive as long as connection is


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 164 at r1 (raw file):

Previously, weiminyu (Weimin Yu) wrote…

Add a few tests?

Done.


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 165 at r1 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

Annotate sessionInfo above with @Nullable if null is an expected value for it.

What sessionInfo above? This is the value of the cookie, which can potentially be null


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 171 at r1 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

Make this compiled pattern a static final on the class, so it doesn't need to be compiled from scratch during each request.

It's not compiled from scratch during each request. It only does it once when connection is established and then it's saved in maybeRegistrarId


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 178 at r1 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

It's a little confusing that this helper method is both setting an instance variable, and returning that value. (And even worse, that the value is being extracted and set during a conditional check, which typically you wouldn't think would modify any state.) I'd suggest doing one or the other, not both.

Fair enough


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 182 at r1 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

This seems like a pretty broad catch, when all you really need to catch seems to be IllegalArgumentException thrown by BaseEncoding.decode()? Are there other exceptions at play here?

The reason for broad catch was to eliminate any chance of runtime failures. This is not essential functionality which is on a hot pathway, so I tried to be little extra careful.

@CydeWeys CydeWeys left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewable status: 0 of 4 files reviewed, 4 unresolved discussions (waiting on @ptkach and @weiminyu)


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 165 at r1 (raw file):

Previously, ptkach (Pavlo Tkach) wrote…

What sessionInfo above? This is the value of the cookie, which can potentially be null

private Optional<String> extractRegistrarIdFromSessionInfo(String sessionInfo) {

should be

private Optional<String> extractRegistrarIdFromSessionInfo(@Nullable String sessionInfo) {


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 171 at r1 (raw file):

Previously, ptkach (Pavlo Tkach) wrote…

It's not compiled from scratch during each request. It only does it once when connection is established and then it's saved in maybeRegistrarId

What if the connection consists of thousands of invalid requests, none of which contain a registrar ID? Won't it keep re-compiling this pattern each time?

@ptkach
ptkach force-pushed the proxyRegistrarId branch from 2509b1a to 15a106b Compare August 5, 2025 16:44

@ptkach ptkach left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Reviewable status: 0 of 4 files reviewed, 4 unresolved discussions (waiting on @CydeWeys and @weiminyu)


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 165 at r1 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

private Optional<String> extractRegistrarIdFromSessionInfo(String sessionInfo) {

should be

private Optional<String> extractRegistrarIdFromSessionInfo(@Nullable String sessionInfo) {

Done


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 171 at r1 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

What if the connection consists of thousands of invalid requests, none of which contain a registrar ID? Won't it keep re-compiling this pattern each time?

This will only execute after epp login, so session should be valid and sessionInfo == null should pass, which will happen only once


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 183 at r1 (raw file):

Previously, CydeWeys (Ben McIlwain) wrote…

How about "Failed to decode session info from Base64"

And should we be logging the session info? Might that not put sensitive data in the logs that shouldn't be there?

Done.

@CydeWeys CydeWeys left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewable status: 0 of 4 files reviewed, 2 unresolved discussions (waiting on @ptkach and @weiminyu)


proxy/src/main/java/google/registry/proxy/handler/EppServiceHandler.java line 171 at r1 (raw file):

Previously, ptkach (Pavlo Tkach) wrote…

This will only execute after epp login, so session should be valid and sessionInfo == null should pass, which will happen only once

Right but can't a registrar send thousands of failing login commands all on the same session? Or is that not possible / does this run only after a successful login?

@CydeWeys CydeWeys left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

:lgtm:

Reviewable status: 0 of 4 files reviewed, 1 unresolved discussion (waiting on @weiminyu)

@ptkach
ptkach enabled auto-merge August 5, 2025 17:55

@weiminyu weiminyu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed 2 of 3 files at r1, 1 of 2 files at r2, 1 of 1 files at r3, all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @ptkach)

@ptkach
ptkach added this pull request to the merge queue Aug 5, 2025
Merged via the queue into google:master with commit 95c89bc Aug 5, 2025
9 checks passed
@ptkach
ptkach deleted the proxyRegistrarId branch August 5, 2025 19:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants