Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compliance Violation Listener cleanup of alternate proposal #11301

Conversation

joakime
Copy link
Contributor

@joakime joakime commented Jan 22, 2024

Additional clean of PR #11283 (Alternate proposal of Compliance Violations Listener handling)

@joakime joakime added Bug For general bugs on Jetty side Sponsored This issue affects a user with a commercial support agreement labels Jan 22, 2024
@joakime joakime requested review from gregw and sbordet January 22, 2024 21:01
@joakime joakime self-assigned this Jan 22, 2024
@@ -363,4 +359,62 @@ private static Set<Violation> copyOf(Set<Violation> violations)
return EnumSet.noneOf(Violation.class);
return EnumSet.copyOf(violations);
}

public static void checkHttpCompliance(MetaData.Request request, HttpCompliance mode,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Used by HTTP/2 and HTTP/3

/**
* A Listener that represents multiple user {@link ComplianceViolation.Listener} instances
*/
class ListenerCollection implements Listener
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved to AbstractConnector (as it was the only place using it)

Copy link
Contributor

@gregw gregw left a comment

Choose a reason for hiding this comment

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

So far so good....

@@ -85,12 +85,14 @@ public Runnable onRequest(HeadersFrame frame)
{
_requestMetaData = (MetaData.Request)frame.getMetaData();

ComplianceViolation.Listener listener = Server.getComplianceViolationListener(_httpChannel.getConnectionMetaData().getConnector()).initialize();
// Grab freshly initialized ComplianceViolation.Listener here, no need to reinitialize.
ComplianceViolation.Listener listener = _httpChannel.getComponents().getComplianceViolationListener();
Copy link
Contributor

Choose a reason for hiding this comment

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

@sbordet This is the exposed violations listeners in components. I agree it is kind of funny... but is it really any different to the exposed HttpConfiguration (see change below)?

The HttpConfiguration is public API, but also has getters for lists of Customizers, which users are not meant to use directly.

What if we moved the compliance listeners to HttpConfiguration? They'd still be able to be associated with a particular connector if desired? It would also be very much more explicit rather than just adding beans.

Copy link
Contributor Author

@joakime joakime Jan 23, 2024

Choose a reason for hiding this comment

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

If we move the configuration of ComplianceViolation.Listener (from being beans on Connector or Server) to HttpConfiguration then that simplifies a bunch of things too.

We could have methods:

  • addComplianceViolationListener(ComplianceViolation.Listener)
  • removeComplianceViolationListener(ComplianceViolation.Listener)
  • getComplianceViolationListeners() - returns the list of listeners
  • getActiveComplianceViolationListener() - returns the active (possibly composite, possible NOOP) ComplianceViolation.Listener suitable to use in the code.

The existence of any added listener would be the equivalent of HttpConfiguration.isNotifyComplianceViolations() of true (no need for this boolean).
We could also get rid of Server.getComplianceViolationListener(Connector connector) in favor of just using the HttpConfiguration.getActiveComplianceViolationListener().

This however, wouldn't get rid of, or change, the existing storage and management from HttpChannelState tho. right?
We still need the initialize() / onBeginRequest() / onEndRequest() calls from the right places in HTTP/1, HTTP/2, and HTTP/3

@@ -258,6 +258,7 @@ private HttpChannel pollHttpChannel()
httpChannel = httpChannels.poll();
if (httpChannel == null)
httpChannel = httpChannelFactory.newHttpChannel(this);
httpChannel.init();
Copy link
Contributor

Choose a reason for hiding this comment

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

I know I first used the "initialize" verb... but is it really the right verb? perhaps prepare?

Anyway, failing a better name, can this at least be initialize

Comment on lines +203 to +206
// TODO: it's a bit odd to hang onto a ComplianceViolation.Listener here.
// as that would require the user to pass it in. Maybe a List<Event> violations instead?
// that the ee10 layer could use?
private ComplianceViolation.Listener complianceViolationListener;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm -1 on keeping lists of violations just in case later on there is a violation listener we need to pass it too.

Just have this field with an optional constructor. If it is constructed without the listener, then there is no listener.

@@ -58,18 +57,27 @@ public HttpConfiguration getHttpConfiguration()
@Override
public void configure(Connector connector)
{
if (isRecordHttpComplianceViolations())
// TODO: need HTTP/2 and HTTP/3 version of this
if (getHttpConfiguration().isNotifyComplianceViolations())
Copy link
Contributor

@gregw gregw Jan 22, 2024

Choose a reason for hiding this comment

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

Yeah this is screaming to me now to just add the listeners to the HttpConfiguration. Why look at the configuration to decide if to add a bean that is looked for elsewhere.

@gregw
Copy link
Contributor

gregw commented Jan 22, 2024

I've closed #11283 in favour of this PR. But I'll repeat my (updated) review response from there here so it is read:

@sbordet I'm a hard -1 on an attribute/bean to lookup the listeners. It is just in too many places. With a field, then the JIT has some chance of optimizing for a null or constant value, but with an attribute we will be looking in a map (probably behind a wrapper behind a lazy atomic reference) every time. It is used too frequently in too many places to put into just an attribute.

I agree that it is a little strange to "initialize" the listener in the "recycle" step, but that is because there is no even before onRequest that can be used to initialize the listener for any violations that occur before there is a request. I could add a initialize event to the HttpChannel, but that feels more intrusive..... hmmm but that would solve the creating a new listener for a channel that would not be used again.... I'll investigate.... oh look @joakime did that already in this PR!

I also kind of agree that Components is not exactly the right place to surface this. HttpChannelState is the right place... but then we do not have a common way to navigate from Components to HttpChannelState... other than down casting Components. Perhaps that will be sufficient for this? OR perhaps we just move the listeners to HttpConfiguration?

@joakime
Copy link
Contributor Author

joakime commented Jan 23, 2024

Note: the original PR #11254 has been updated with the changes from proposal 2 (gregs) and 3 (this one).

@gregw
Copy link
Contributor

gregw commented Jan 23, 2024

@joakime Ah no! We still need to have the listeners as a field on the HttpChannelState, as that is where the lifecycle is. If the combined listener is on the HttpConfiguration, then we can't call init on it.

I don't mind moving the the listeners to HttpConfiguration anyway.... it just doesn't solve the problem of moving them out of Components.

@gregw
Copy link
Contributor

gregw commented Jan 23, 2024

closed in favor of #11254

@gregw gregw closed this Jan 23, 2024
@gregw
Copy link
Contributor

gregw commented Jan 23, 2024

@joakime I have pushed a change to move the listeners to config, but still with the access via Components. I'm struggling to find a better way than that.

@joakime joakime deleted the fix/12.0.x/cookie-compliance-logging3 branch February 28, 2024 13:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug For general bugs on Jetty side Sponsored This issue affects a user with a commercial support agreement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants