JEP 183: HTTP Cross-Origin Resource Sharing

OwnerMichael McMahon
Created2013/03/26 20:00
Updated2014/07/10 20:49
TypeFeature
StatusCandidate
Componentcore-libs / java.net
ScopeSE
Discussionnet dash dev at openjdk dot java dot net
EffortS
DurationS
Priority4
Reviewed byAlan Bateman, Chris Hegarty, Jeffrey Nisewanger
Endorsed byBrian Goetz
Issue8046173
DependsJEP 140: Limited doPrivileged

Summary

Implement the W3C Cross Origin Resource Sharing (CORS) protocol in order to align Java's HTTP stack with HTML5 and current web browsers.

Motivation

Java code running under a security manager is currently restricted by the same origin policy: Network connections can only be made to the code's origin unless explicit permissions are granted.

The World-Wide Web is moving towards a less-restrictive policy based on an open standard called Cross Origin Resource Sharing (CORS). CORS defines a protocol by which a web client can interact with a server to authorize specific cross-origin requests.

Description

The CORS protocol adds some extra headers, processing steps, and possibly an additional request/response round-trip when interacting with a resource named by a URL. CORS defines certain HTTP requests as simple requests. Simple requests are always allowed without prior authorization from the server. A non-simple request must be preceded by a special pre-flight request to ask the server if the non-simple request will be allowed. Authorization results are cached.

The CORS protocol is largely transparent to application code. A small API may be defined whose principal function is to enable CORS on a per-connection basis, but a system property may also be defined to enable it globally on all connections, so that existing code can leverage CORS without needing to be modified. The API would also cover the use cases where the following flags need to be specified:

The API might look like this:

public class java.net.HttpURLConnection {
    :
    public void setCORSParameters(
        boolean enable,
        boolean omitCredentials,
        boolean forcePreflight
    ) { ... }
}

Code example:

 URL url = new URL("http://www.server.com/cross-origin-request/");
 HttpURLConnection urlc = (HttpURLConnection)url.openConnection();
 urlc.setCORSParameters(true, false, false);
 urlc.setRequestMethod("POST");
 urlc.setRequestProperty("Content-Type", "application/xml");
 urlc.setDoOutput(true);
 OutputStream os = urlc.getOutputStream();
 os.write(... request body ...);
 ...

The CORS protocol definition is stable but not yet final, so this feature might not initially be implemented as a public API in the java.net package. If not then it will be implemented as a JDK-specific API or system property, which could evolve as needed along with the protocol.

Testing

This feature introduces a new protocol mechanism that needs to be tested, either against real third party HTTP servers or using tests implemented on top of the JDK's built-in HTTP server.

A simple unit-test framework has been developed using the JDK's HTTP server. A test is specified as a set comprising a client API call, expected HTTP requests and responses as seen by the server, and an API response as seen by the client. The development work for this feature will include a set of such unit tests.

Risks and Assumptions

The CORS protocol definition is a W3C "Candidate Recommendation" as of January 2013. It was intended to become a "Proposed Recommendation" by the beginning of March, but that did not happen. If the CORS protocol definition changes then this feature will have to be revised accordingly.

Dependences

This feature depends on JEP 140: Limited doPrivileged.

Impact