17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.net.www.protocol.jrt;
27
28 import java.io.ByteArrayInputStream;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.UncheckedIOException;
32 import java.net.MalformedURLException;
33 import java.net.URL;
34
35 import jdk.internal.jimage.ImageReader;
36 import jdk.internal.jimage.ImageReader.Node;
37 import jdk.internal.jimage.ImageReaderFactory;
38
39 import sun.net.www.ParseUtil;
40 import sun.net.www.URLConnection;
41
42 /**
43 * URLConnection implementation that can be used to connect to resources
44 * contained in the runtime image. See section "New URI scheme for naming stored
45 * modules, classes, and resources" in <a href="https://openjdk.org/jeps/220">
46 * JEP 220</a>.
47 */
48 public class JavaRuntimeURLConnection extends URLConnection {
49
50 // ImageReader to access resources in jimage.
51 private static final ImageReader READER = ImageReaderFactory.getImageReader();
52
53 // The module and resource name in the URL (i.e. "jrt:/[$MODULE[/$PATH]]").
54 //
55 // The module name is not percent-decoded, and can be empty.
56 private final String module;
57 // The resource name permits UTF-8 percent encoding of non-ASCII characters.
58 private final String path;
59
60 // The resource node (non-null when connected).
61 private Node resourceNode;
62
63 JavaRuntimeURLConnection(URL url) throws IOException {
64 super(url);
65 String urlPath = url.getPath();
66 if (urlPath.isEmpty() || urlPath.charAt(0) != '/') {
67 throw new MalformedURLException(url + " missing path or /");
68 }
69 int pathSep = urlPath.indexOf('/', 1);
70 if (pathSep == -1) {
71 // No trailing resource path. This can never "connect" or return a
92 throw new IOException(module + "/" + path + " not found");
93 }
94 this.resourceNode = node;
95 super.connected = true;
96 }
97 return resourceNode;
98 }
99
100 @Override
101 public void connect() throws IOException {
102 connectResourceNode();
103 }
104
105 @Override
106 public InputStream getInputStream() throws IOException {
107 return new ByteArrayInputStream(READER.getResource(connectResourceNode()));
108 }
109
110 @Override
111 public long getContentLengthLong() {
112 try {
113 return connectResourceNode().size();
114 } catch (IOException ioe) {
115 return -1L;
116 }
117 }
118
119 @Override
120 public int getContentLength() {
121 long len = getContentLengthLong();
122 return len > Integer.MAX_VALUE ? -1 : (int)len;
123 }
124
125 // Perform percent decoding of the resource name/path from the URL.
126 private static String percentDecode(String path) throws MalformedURLException {
127 // Any additional special case decoding logic should go here.
128 try {
129 return ParseUtil.decode(path);
130 } catch (IllegalArgumentException e) {
131 throw new MalformedURLException(e.getMessage());
132 }
133 }
134 }
|
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.net.www.protocol.jrt;
27
28 import java.io.ByteArrayInputStream;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.UncheckedIOException;
32 import java.net.MalformedURLException;
33 import java.net.URL;
34
35 import jdk.internal.jimage.ImageReader;
36 import jdk.internal.jimage.ImageReader.Node;
37 import jdk.internal.jimage.SystemImageReader;
38
39 import sun.net.www.ParseUtil;
40 import sun.net.www.URLConnection;
41
42 /**
43 * URLConnection implementation that can be used to connect to resources
44 * contained in the runtime image. See section "New URI scheme for naming stored
45 * modules, classes, and resources" in <a href="https://openjdk.org/jeps/220">
46 * JEP 220</a>.
47 */
48 public class JavaRuntimeURLConnection extends URLConnection {
49
50 // ImageReader to access resources in jimage.
51 private static final ImageReader READER = SystemImageReader.get();
52
53 // The module and resource name in the URL (i.e. "jrt:/[$MODULE[/$PATH]]").
54 //
55 // The module name is not percent-decoded, and can be empty.
56 private final String module;
57 // The resource name permits UTF-8 percent encoding of non-ASCII characters.
58 private final String path;
59
60 // The resource node (non-null when connected).
61 private Node resourceNode;
62
63 JavaRuntimeURLConnection(URL url) throws IOException {
64 super(url);
65 String urlPath = url.getPath();
66 if (urlPath.isEmpty() || urlPath.charAt(0) != '/') {
67 throw new MalformedURLException(url + " missing path or /");
68 }
69 int pathSep = urlPath.indexOf('/', 1);
70 if (pathSep == -1) {
71 // No trailing resource path. This can never "connect" or return a
92 throw new IOException(module + "/" + path + " not found");
93 }
94 this.resourceNode = node;
95 super.connected = true;
96 }
97 return resourceNode;
98 }
99
100 @Override
101 public void connect() throws IOException {
102 connectResourceNode();
103 }
104
105 @Override
106 public InputStream getInputStream() throws IOException {
107 return new ByteArrayInputStream(READER.getResource(connectResourceNode()));
108 }
109
110 @Override
111 public long getContentLengthLong() {
112 // Note: UncheckedIOException is thrown by the Node subclass in
113 // ExplodedImage (this not obvious, so worth calling out).
114 try {
115 return connectResourceNode().size();
116 } catch (IOException | UncheckedIOException ioe) {
117 return -1L;
118 }
119 }
120
121 @Override
122 public int getContentLength() {
123 long len = getContentLengthLong();
124 return len > Integer.MAX_VALUE ? -1 : (int)len;
125 }
126
127 // Perform percent decoding of the resource name/path from the URL.
128 private static String percentDecode(String path) throws MalformedURLException {
129 if (path.indexOf('%') == -1) {
130 // Nothing to decode (overwhelmingly common case).
131 return path;
132 }
133 // Any additional special case decoding logic should go here.
134 try {
135 return ParseUtil.decode(path);
136 } catch (IllegalArgumentException e) {
137 throw new MalformedURLException(e.getMessage());
138 }
139 }
140 }
|