Skip to content

Commit 2ceb7b4

Browse files
committed
Extract LoaderHidingResource as a top-level type
See gh-39472
1 parent 3ff0979 commit 2ceb7b4

File tree

2 files changed

+186
-158
lines changed

2 files changed

+186
-158
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/JettyServletWebServerFactory.java

Lines changed: 0 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,18 @@
1717
package org.springframework.boot.web.embedded.jetty;
1818

1919
import java.io.File;
20-
import java.io.IOException;
21-
import java.io.InputStream;
2220
import java.net.InetSocketAddress;
23-
import java.net.URI;
2421
import java.net.URL;
25-
import java.nio.channels.ReadableByteChannel;
26-
import java.nio.file.Path;
2722
import java.time.Duration;
28-
import java.time.Instant;
2923
import java.util.ArrayList;
3024
import java.util.Arrays;
3125
import java.util.Collection;
3226
import java.util.EventListener;
33-
import java.util.Iterator;
3427
import java.util.LinkedHashSet;
3528
import java.util.List;
3629
import java.util.Objects;
3730
import java.util.Set;
38-
import java.util.Spliterator;
3931
import java.util.UUID;
40-
import java.util.function.Consumer;
4132

4233
import jakarta.servlet.http.Cookie;
4334
import org.eclipse.jetty.ee10.servlet.ErrorHandler;
@@ -79,7 +70,6 @@
7970
import org.eclipse.jetty.session.FileSessionDataStore;
8071
import org.eclipse.jetty.session.SessionConfig;
8172
import org.eclipse.jetty.util.Callback;
82-
import org.eclipse.jetty.util.resource.CombinedResource;
8373
import org.eclipse.jetty.util.resource.Resource;
8474
import org.eclipse.jetty.util.resource.ResourceFactory;
8575
import org.eclipse.jetty.util.resource.URLResourceFactory;
@@ -593,154 +583,6 @@ private void addJettyErrorPages(ErrorHandler errorHandler, Collection<ErrorPage>
593583
}
594584
}
595585

596-
private static final class LoaderHidingResource extends Resource {
597-
598-
private static final String LOADER_RESOURCE_PATH_PREFIX = "/org/springframework/boot/";
599-
600-
private final Resource base;
601-
602-
private final Resource delegate;
603-
604-
private LoaderHidingResource(Resource base, Resource delegate) {
605-
this.base = base;
606-
this.delegate = delegate;
607-
}
608-
609-
@Override
610-
public void forEach(Consumer<? super Resource> action) {
611-
this.delegate.forEach(action);
612-
}
613-
614-
@Override
615-
public Path getPath() {
616-
return this.delegate.getPath();
617-
}
618-
619-
@Override
620-
public boolean isContainedIn(Resource r) {
621-
return this.delegate.isContainedIn(r);
622-
}
623-
624-
@Override
625-
public Iterator<Resource> iterator() {
626-
if (this.delegate instanceof CombinedResource) {
627-
return list().iterator();
628-
}
629-
return List.<Resource>of(this).iterator();
630-
}
631-
632-
@Override
633-
public boolean equals(Object obj) {
634-
return this.delegate.equals(obj);
635-
}
636-
637-
@Override
638-
public int hashCode() {
639-
return this.delegate.hashCode();
640-
}
641-
642-
@Override
643-
public boolean exists() {
644-
return this.delegate.exists();
645-
}
646-
647-
@Override
648-
public Spliterator<Resource> spliterator() {
649-
return this.delegate.spliterator();
650-
}
651-
652-
@Override
653-
public boolean isDirectory() {
654-
return this.delegate.isDirectory();
655-
}
656-
657-
@Override
658-
public boolean isReadable() {
659-
return this.delegate.isReadable();
660-
}
661-
662-
@Override
663-
public Instant lastModified() {
664-
return this.delegate.lastModified();
665-
}
666-
667-
@Override
668-
public long length() {
669-
return this.delegate.length();
670-
}
671-
672-
@Override
673-
public URI getURI() {
674-
return this.delegate.getURI();
675-
}
676-
677-
@Override
678-
public String getName() {
679-
return this.delegate.getName();
680-
}
681-
682-
@Override
683-
public String getFileName() {
684-
return this.delegate.getFileName();
685-
}
686-
687-
@Override
688-
public InputStream newInputStream() throws IOException {
689-
return this.delegate.newInputStream();
690-
}
691-
692-
@Override
693-
@SuppressWarnings({ "deprecation", "removal" })
694-
public ReadableByteChannel newReadableByteChannel() throws IOException {
695-
return this.delegate.newReadableByteChannel();
696-
}
697-
698-
@Override
699-
public List<Resource> list() {
700-
return this.delegate.list().stream().filter(this::nonLoaderResource).toList();
701-
}
702-
703-
private boolean nonLoaderResource(Resource resource) {
704-
Path prefix = this.base.getPath().resolve(Path.of("org", "springframework", "boot"));
705-
return !resource.getPath().startsWith(prefix);
706-
}
707-
708-
@Override
709-
public Resource resolve(String subUriPath) {
710-
if (subUriPath.startsWith(LOADER_RESOURCE_PATH_PREFIX)) {
711-
return null;
712-
}
713-
Resource resolved = this.delegate.resolve(subUriPath);
714-
return (resolved != null) ? new LoaderHidingResource(this.base, resolved) : null;
715-
}
716-
717-
@Override
718-
public boolean isAlias() {
719-
return this.delegate.isAlias();
720-
}
721-
722-
@Override
723-
public URI getRealURI() {
724-
return this.delegate.getRealURI();
725-
}
726-
727-
@Override
728-
public void copyTo(Path destination) throws IOException {
729-
this.delegate.copyTo(destination);
730-
}
731-
732-
@Override
733-
public Collection<Resource> getAllResources() {
734-
return this.delegate.getAllResources().stream().filter(this::nonLoaderResource).toList();
735-
}
736-
737-
@Override
738-
public String toString() {
739-
return this.delegate.toString();
740-
}
741-
742-
}
743-
744586
/**
745587
* {@link AbstractConfiguration} to apply {@code @WebListener} classes.
746588
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/*
2+
* Copyright 2012-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.web.embedded.jetty;
18+
19+
import java.io.IOException;
20+
import java.io.InputStream;
21+
import java.net.URI;
22+
import java.nio.channels.ReadableByteChannel;
23+
import java.nio.file.Path;
24+
import java.time.Instant;
25+
import java.util.Collection;
26+
import java.util.Iterator;
27+
import java.util.List;
28+
import java.util.Spliterator;
29+
import java.util.function.Consumer;
30+
31+
import org.eclipse.jetty.util.resource.CombinedResource;
32+
import org.eclipse.jetty.util.resource.Resource;
33+
34+
/**
35+
* A custom {@link Resource} that hides Spring Boot's loader classes, preventing them from
36+
* being served over HTTP.
37+
*
38+
* @author Andy Wilkinson
39+
*/
40+
final class LoaderHidingResource extends Resource {
41+
42+
private static final String LOADER_RESOURCE_PATH_PREFIX = "/org/springframework/boot/";
43+
44+
private final Resource base;
45+
46+
private final Resource delegate;
47+
48+
LoaderHidingResource(Resource base, Resource delegate) {
49+
this.base = base;
50+
this.delegate = delegate;
51+
}
52+
53+
@Override
54+
public void forEach(Consumer<? super Resource> action) {
55+
this.delegate.forEach(action);
56+
}
57+
58+
@Override
59+
public Path getPath() {
60+
return this.delegate.getPath();
61+
}
62+
63+
@Override
64+
public boolean isContainedIn(Resource r) {
65+
return this.delegate.isContainedIn(r);
66+
}
67+
68+
@Override
69+
public Iterator<Resource> iterator() {
70+
if (this.delegate instanceof CombinedResource) {
71+
return list().iterator();
72+
}
73+
return List.<Resource>of(this).iterator();
74+
}
75+
76+
@Override
77+
public boolean equals(Object obj) {
78+
return this.delegate.equals(obj);
79+
}
80+
81+
@Override
82+
public int hashCode() {
83+
return this.delegate.hashCode();
84+
}
85+
86+
@Override
87+
public boolean exists() {
88+
return this.delegate.exists();
89+
}
90+
91+
@Override
92+
public Spliterator<Resource> spliterator() {
93+
return this.delegate.spliterator();
94+
}
95+
96+
@Override
97+
public boolean isDirectory() {
98+
return this.delegate.isDirectory();
99+
}
100+
101+
@Override
102+
public boolean isReadable() {
103+
return this.delegate.isReadable();
104+
}
105+
106+
@Override
107+
public Instant lastModified() {
108+
return this.delegate.lastModified();
109+
}
110+
111+
@Override
112+
public long length() {
113+
return this.delegate.length();
114+
}
115+
116+
@Override
117+
public URI getURI() {
118+
return this.delegate.getURI();
119+
}
120+
121+
@Override
122+
public String getName() {
123+
return this.delegate.getName();
124+
}
125+
126+
@Override
127+
public String getFileName() {
128+
return this.delegate.getFileName();
129+
}
130+
131+
@Override
132+
public InputStream newInputStream() throws IOException {
133+
return this.delegate.newInputStream();
134+
}
135+
136+
@Override
137+
@SuppressWarnings({ "deprecation", "removal" })
138+
public ReadableByteChannel newReadableByteChannel() throws IOException {
139+
return this.delegate.newReadableByteChannel();
140+
}
141+
142+
@Override
143+
public List<Resource> list() {
144+
return this.delegate.list().stream().filter(this::nonLoaderResource).toList();
145+
}
146+
147+
private boolean nonLoaderResource(Resource resource) {
148+
Path prefix = this.base.getPath().resolve(Path.of("org", "springframework", "boot"));
149+
return !resource.getPath().startsWith(prefix);
150+
}
151+
152+
@Override
153+
public Resource resolve(String subUriPath) {
154+
if (subUriPath.startsWith(LOADER_RESOURCE_PATH_PREFIX)) {
155+
return null;
156+
}
157+
Resource resolved = this.delegate.resolve(subUriPath);
158+
return (resolved != null) ? new LoaderHidingResource(this.base, resolved) : null;
159+
}
160+
161+
@Override
162+
public boolean isAlias() {
163+
return this.delegate.isAlias();
164+
}
165+
166+
@Override
167+
public URI getRealURI() {
168+
return this.delegate.getRealURI();
169+
}
170+
171+
@Override
172+
public void copyTo(Path destination) throws IOException {
173+
this.delegate.copyTo(destination);
174+
}
175+
176+
@Override
177+
public Collection<Resource> getAllResources() {
178+
return this.delegate.getAllResources().stream().filter(this::nonLoaderResource).toList();
179+
}
180+
181+
@Override
182+
public String toString() {
183+
return this.delegate.toString();
184+
}
185+
186+
}

0 commit comments

Comments
 (0)