Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.net.*;
import javax.net.ssl.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.text.*;
Expand Down Expand Up @@ -59,6 +60,9 @@ class ExchangeImpl {

/* for formatting the Date: header */
private static final DateTimeFormatter FORMATTER;
private static final boolean perExchangeAttributes =
!System.getProperty("jdk.httpserver.attributes", "")
.equals("context");
Comment on lines +63 to +65
Copy link
Member

Choose a reason for hiding this comment

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

The property will have to be documented somewhere such as the jdk.httpserver module-info. But, I'm wondering if fairly obscure properties like this might be better off "buried" in the net.properties config file. I think there's a case for putting all such "compatibility" flags somewhere out of the way like that. If we were to do that, you would need to access the property using sun.net.NetProperties.

Any other views on this?

Copy link
Author

Choose a reason for hiding this comment

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

I can switch to sun.net.NetProperties if you so desire.

Copy link
Member

@Michael-Mc-Mahon Michael-Mc-Mahon Oct 8, 2025

Choose a reason for hiding this comment

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

Yeah, I think we should put the property in net.properties something like this:

  # Prior to JDK 26, the HttpExchange attribute map was shared with the enclosing HttpContext.
  # Since JDK 26, by default, exchange attributes are per-exchange and the context attributes must
  # be accessed by calling getHttpContext().getAttributes(). Uncomment this property to
  # restore the pre JDK 26 behavior.
  #
  # jdk.httpserver.attributes=context

Then I think we should add a sentence at the end of the jdk.httpserver module-info to say that additional
system/networking properties may be defined in net.properties

static {
String pattern = "EEE, dd MMM yyyy HH:mm:ss zzz";
FORMATTER = DateTimeFormatter.ofPattern(pattern, Locale.US)
Expand All @@ -76,7 +80,7 @@ class ExchangeImpl {
PlaceholderOutputStream uos_orig;

boolean sentHeaders; /* true after response headers sent */
Map<String,Object> attributes;
final Map<String,Object> attributes;
int rcode = -1;
HttpPrincipal principal;
ServerImpl server;
Expand All @@ -91,6 +95,9 @@ class ExchangeImpl {
this.uri = u;
this.connection = connection;
this.reqContentLen = len;
this.attributes = perExchangeAttributes
? new ConcurrentHashMap<>()
: getHttpContext().getAttributes();
/* ros only used for headers, body written directly to stream */
this.ros = req.outputStream();
this.ris = req.inputStream();
Expand Down Expand Up @@ -361,26 +368,15 @@ public SSLSession getSSLSession () {
}

public Object getAttribute (String name) {
if (name == null) {
throw new NullPointerException ("null name parameter");
}
if (attributes == null) {
attributes = getHttpContext().getAttributes();
}
return attributes.get (name);
return attributes.get(Objects.requireNonNull(name, "null name parameter"));
}

public void setAttribute (String name, Object value) {
if (name == null) {
throw new NullPointerException ("null name parameter");
}
if (attributes == null) {
attributes = getHttpContext().getAttributes();
}
var key = Objects.requireNonNull(name, "null name parameter");
if (value != null) {
attributes.put (name, value);
attributes.put(key, value);
} else {
attributes.remove (name);
attributes.remove(key);
}
}

Expand Down