Skip to content

Commit b2e9f84

Browse files
committed
Plug URIResolver into EndpointReferenceUtils
1 parent 0cc2bca commit b2e9f84

2 files changed

Lines changed: 149 additions & 11 deletions

File tree

core/src/main/java/org/apache/cxf/ws/addressing/EndpointReferenceUtils.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
package org.apache.cxf.ws.addressing;
2121

2222
import java.io.ByteArrayInputStream;
23-
import java.io.InputStream;
2423
import java.lang.ref.Reference;
2524
import java.lang.ref.SoftReference;
2625
import java.net.MalformedURLException;
@@ -72,6 +71,7 @@
7271
import org.apache.cxf.helpers.LoadingByteArrayOutputStream;
7372
import org.apache.cxf.resource.ExtendedURIResolver;
7473
import org.apache.cxf.resource.ResourceManager;
74+
import org.apache.cxf.resource.URIResolver;
7575
import org.apache.cxf.service.model.SchemaInfo;
7676
import org.apache.cxf.service.model.ServiceInfo;
7777
import org.apache.cxf.staxutils.StaxUtils;
@@ -550,20 +550,17 @@ private static Schema createSchema(ServiceInfo serviceInfo, Bus b) {
550550
&& !schemaSourcesMap.containsKey(sch.getSourceURI() + ':'
551551
+ sch.getTargetNamespace())) {
552552

553-
InputStream ins = null;
554-
try {
555-
URL url = new URL(sch.getSourceURI());
556-
ins = url.openStream();
553+
LoadingByteArrayOutputStream out = new LoadingByteArrayOutputStream();
554+
try (URIResolver resolver = new URIResolver(sch.getSourceURI())) {
555+
if (resolver.getInputStream() == null) {
556+
sch.write(out);
557+
} else {
558+
IOUtils.copyAndCloseInput(resolver.getInputStream(), out);
559+
}
557560
} catch (Exception e) {
558561
//ignore, we'll just use what we have. (though
559562
//bugs in XmlSchema could make this less useful)
560-
}
561-
562-
LoadingByteArrayOutputStream out = new LoadingByteArrayOutputStream();
563-
if (ins == null) {
564563
sch.write(out);
565-
} else {
566-
IOUtils.copyAndCloseInput(ins, out);
567564
}
568565

569566
schemaSourcesMap.put(sch.getSourceURI() + ':'
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.cxf.ws.addressing;
21+
22+
import java.io.ByteArrayInputStream;
23+
import java.io.OutputStream;
24+
import java.net.ServerSocket;
25+
import java.net.Socket;
26+
import java.nio.charset.StandardCharsets;
27+
import java.util.concurrent.atomic.AtomicBoolean;
28+
29+
import javax.xml.validation.Schema;
30+
31+
import org.w3c.dom.Document;
32+
33+
import org.apache.cxf.resource.URIResolver;
34+
import org.apache.cxf.service.model.SchemaInfo;
35+
import org.apache.cxf.service.model.ServiceInfo;
36+
import org.apache.cxf.staxutils.StaxUtils;
37+
import org.apache.ws.commons.schema.XmlSchema;
38+
39+
import org.junit.Test;
40+
41+
import static org.junit.Assert.assertFalse;
42+
import static org.junit.Assert.assertNotNull;
43+
import static org.junit.Assert.assertTrue;
44+
45+
public class EndpointReferenceUtilsTest {
46+
47+
@Test
48+
public void testGetSchemaCanOpenSourceUriAllowedByDefaultSchemes() throws Exception {
49+
try (LocalHttpProbeServer probeServer = new LocalHttpProbeServer()) {
50+
String sourceUri = "http://127.0.0.1:" + probeServer.getPort() + "/schema.xsd";
51+
ServiceInfo serviceInfo = createServiceInfo(sourceUri);
52+
53+
Schema schema = EndpointReferenceUtils.getSchema(serviceInfo, null);
54+
assertNotNull(schema);
55+
56+
probeServer.awaitCompletion();
57+
assertTrue("Default allowed schemes should permit opening sourceURI", probeServer.wasConnected());
58+
}
59+
}
60+
61+
@Test
62+
public void testGetSchemaDoesNotOpenDisallowedFtpSourceUri() throws Exception {
63+
try (LocalHttpProbeServer probeServer = new LocalHttpProbeServer()) {
64+
String sourceUri = "ftp://127.0.0.1:" + probeServer.getPort() + "/schema.xsd";
65+
66+
assertFalse("ftp scheme should be disallowed by default",
67+
URIResolver.getAllowedSchemes().contains("ftp"));
68+
69+
ServiceInfo serviceInfo = createServiceInfo(sourceUri);
70+
Schema schema = EndpointReferenceUtils.getSchema(serviceInfo, null);
71+
assertNotNull(schema);
72+
73+
probeServer.awaitCompletion();
74+
assertFalse("Disallowed sourceURI should not be opened", probeServer.wasConnected());
75+
}
76+
}
77+
78+
private ServiceInfo createServiceInfo(String sourceUri) throws Exception {
79+
String namespace = "urn:test:endpoint:reference:utils";
80+
String schemaText =
81+
"<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema' "
82+
+ "targetNamespace='" + namespace + "' elementFormDefault='qualified'>"
83+
+ "<xsd:element name='value' type='xsd:string'/>"
84+
+ "</xsd:schema>";
85+
86+
Document doc = StaxUtils.read(new ByteArrayInputStream(schemaText.getBytes(StandardCharsets.UTF_8)));
87+
88+
ServiceInfo serviceInfo = new ServiceInfo();
89+
XmlSchema xmlSchema = serviceInfo.getXmlSchemaCollection().read(doc.getDocumentElement(), sourceUri);
90+
91+
SchemaInfo schemaInfo = new SchemaInfo(namespace);
92+
schemaInfo.setSchema(xmlSchema);
93+
schemaInfo.setSystemId("memory:/schema.xsd");
94+
serviceInfo.addSchema(schemaInfo);
95+
96+
return serviceInfo;
97+
}
98+
99+
private static final class LocalHttpProbeServer implements AutoCloseable {
100+
private final ServerSocket serverSocket;
101+
private final AtomicBoolean connected = new AtomicBoolean();
102+
private final Thread thread;
103+
104+
private LocalHttpProbeServer() throws Exception {
105+
this.serverSocket = new ServerSocket(0);
106+
this.serverSocket.setSoTimeout(750);
107+
this.thread = new Thread(this::acceptOneConnection, "EndpointReferenceUtilsTest-HttpProbe");
108+
this.thread.setDaemon(true);
109+
this.thread.start();
110+
}
111+
112+
private void acceptOneConnection() {
113+
try (Socket socket = serverSocket.accept()) {
114+
connected.set(true);
115+
OutputStream out = socket.getOutputStream();
116+
out.write("HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n".getBytes(StandardCharsets.US_ASCII));
117+
out.flush();
118+
} catch (Exception ex) {
119+
// timeout/no connection is expected for this test
120+
}
121+
}
122+
123+
private int getPort() {
124+
return serverSocket.getLocalPort();
125+
}
126+
127+
private boolean wasConnected() {
128+
return connected.get();
129+
}
130+
131+
private void awaitCompletion() throws InterruptedException {
132+
thread.join(1500);
133+
}
134+
135+
@Override
136+
public void close() throws Exception {
137+
serverSocket.close();
138+
awaitCompletion();
139+
}
140+
}
141+
}

0 commit comments

Comments
 (0)