|
21 | 21 | */
|
22 | 22 | package org.exist.http;
|
23 | 23 |
|
24 |
| -import java.io.BufferedReader; |
25 |
| -import java.io.IOException; |
26 |
| -import java.io.InputStream; |
27 |
| -import java.io.InputStreamReader; |
28 |
| -import java.io.OutputStreamWriter; |
29 |
| -import java.io.Writer; |
30 |
| -import java.io.StringReader; |
| 24 | +import java.io.*; |
31 | 25 | import java.net.HttpURLConnection;
|
32 | 26 | import java.net.URL;
|
33 | 27 | import java.net.URLEncoder;
|
| 28 | +import java.util.Optional; |
34 | 29 | import javax.xml.parsers.ParserConfigurationException;
|
35 | 30 |
|
36 | 31 | import com.googlecode.junittoolbox.ParallelRunner;
|
37 | 32 | import org.apache.commons.codec.binary.Base64;
|
38 | 33 | import org.eclipse.jetty.http.HttpStatus;
|
| 34 | +import org.exist.EXistException; |
39 | 35 | import org.exist.Namespaces;
|
| 36 | +import org.exist.collections.Collection; |
| 37 | +import org.exist.collections.triggers.TriggerException; |
40 | 38 | import org.exist.dom.memtree.SAXAdapter;
|
| 39 | +import org.exist.dom.persistent.LockedDocument; |
| 40 | +import org.exist.security.PermissionDeniedException; |
| 41 | +import org.exist.storage.BrokerPool; |
| 42 | +import org.exist.storage.DBBroker; |
| 43 | +import org.exist.storage.lock.Lock; |
| 44 | +import org.exist.storage.txn.Txn; |
| 45 | +import org.exist.test.ExistEmbeddedServer; |
41 | 46 | import org.exist.test.ExistWebServer;
|
| 47 | +import org.exist.test.TestConstants; |
42 | 48 | import org.exist.util.ExistSAXParserFactory;
|
| 49 | +import org.exist.util.LockException; |
| 50 | +import org.exist.util.MimeType; |
| 51 | +import org.exist.util.StringInputSource; |
43 | 52 | import org.exist.xmldb.XmldbURI;
|
44 | 53 | import org.junit.runner.RunWith;
|
45 | 54 | import org.xml.sax.InputSource;
|
@@ -237,11 +246,30 @@ private static String getResourceUriPlus() {
|
237 | 246 | return getServerUri() + XmldbURI.ROOT_COLLECTION + "/test//../test/A-Za-z0-9_~!$&'()*+,;=@%20%23%25%27%2F%3F%5B%5Däöü.xml";
|
238 | 247 | }
|
239 | 248 |
|
| 249 | + @ClassRule |
| 250 | + public static final ExistEmbeddedServer existEmbeddedServer = new ExistEmbeddedServer(true, true); |
240 | 251 |
|
241 | 252 | @BeforeClass
|
242 |
| - public static void createCredentials() { |
| 253 | + public static void setup() throws PermissionDeniedException, IOException, TriggerException { |
243 | 254 | credentials = Base64.encodeBase64String("admin:".getBytes(UTF_8));
|
244 | 255 | badCredentials = Base64.encodeBase64String("johndoe:this pw should fail".getBytes(UTF_8));
|
| 256 | + |
| 257 | + final XmldbURI TEST_XML_DOC_URI = XmldbURI.create("AéB.xml"); |
| 258 | + final XmldbURI TEST_COLLECTION_URI = XmldbURI.create("/db/AéB"); |
| 259 | + final String TEST_XML_DOC = "<foo/>"; |
| 260 | + |
| 261 | + final BrokerPool pool = existEmbeddedServer.getBrokerPool(); |
| 262 | + try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject())); |
| 263 | + final Txn transaction = pool.getTransactionManager().beginTransaction()) { |
| 264 | + try (final Collection col = broker.getOrCreateCollection(transaction, TEST_COLLECTION_URI)) { |
| 265 | + broker.storeDocument(transaction, TEST_XML_DOC_URI, new StringInputSource(TEST_XML_DOC), MimeType.XML_TYPE, col); |
| 266 | + broker.saveCollection(transaction, col); |
| 267 | + } |
| 268 | + |
| 269 | + transaction.commit(); |
| 270 | + } catch (EXistException | SAXException | LockException e) { |
| 271 | + throw new RuntimeException(e); |
| 272 | + } |
245 | 273 | }
|
246 | 274 |
|
247 | 275 | @Test
|
@@ -1036,6 +1064,148 @@ public void execSetUidQueryWithBearerAuth() throws IOException {
|
1036 | 1064 | }
|
1037 | 1065 | }
|
1038 | 1066 |
|
| 1067 | + //test rest server ability to handle encoded characters |
| 1068 | + // all the tests with EncodedPath in function declaration aim to test rest server ability to handle special characters |
| 1069 | + @Test |
| 1070 | + public void doGetEncodedPath() throws IOException { |
| 1071 | + String DOC_URI = getServerUri() + XmldbURI.ROOT_COLLECTION + "/AéB/AéB.xml"; |
| 1072 | + final HttpURLConnection connect = getConnection(DOC_URI); |
| 1073 | + try { |
| 1074 | + connect.setRequestMethod("GET"); |
| 1075 | + connect.connect(); |
| 1076 | + |
| 1077 | + final int r = connect.getResponseCode(); |
| 1078 | + assertEquals("Server returned response code " + r, HttpStatus.OK_200, r); |
| 1079 | + String contentType = connect.getContentType(); |
| 1080 | + final int semicolon = contentType.indexOf(';'); |
| 1081 | + if (semicolon > 0) { |
| 1082 | + contentType = contentType.substring(0, semicolon).trim(); |
| 1083 | + } |
| 1084 | + assertEquals("Server returned content type " + contentType, "application/xml", contentType); |
| 1085 | + |
| 1086 | + String response = readResponse(connect.getInputStream()); |
| 1087 | + |
| 1088 | + //readResponse is appending \r\n to each line that's why its added the expected content |
| 1089 | + assertEquals("Server returned document content " + response,"<foobar/>\r\n",response); |
| 1090 | + } finally { |
| 1091 | + connect.disconnect(); |
| 1092 | + } |
| 1093 | + } |
| 1094 | + |
| 1095 | + @Test |
| 1096 | + public void doHeadEncodedPath() throws IOException { |
| 1097 | + String DOC_URI = getServerUri() + XmldbURI.ROOT_COLLECTION + "/AéB/AéB.xml"; |
| 1098 | + final HttpURLConnection connect = getConnection(DOC_URI); |
| 1099 | + try { |
| 1100 | + connect.setRequestMethod("GET"); |
| 1101 | + connect.connect(); |
| 1102 | + |
| 1103 | + final int r = connect.getResponseCode(); |
| 1104 | + assertEquals("Server returned response code " + r, HttpStatus.OK_200, r); |
| 1105 | + } finally { |
| 1106 | + connect.disconnect(); |
| 1107 | + } |
| 1108 | + } |
| 1109 | + |
| 1110 | + @Test |
| 1111 | + public void doPutEncodedPath() throws IOException { |
| 1112 | + String DOC_URI = getServerUri() + XmldbURI.ROOT_COLLECTION + "/AéB/AéB.xml"; |
| 1113 | + final HttpURLConnection connect = getConnection(DOC_URI); |
| 1114 | + final HttpURLConnection getConnect = getConnection(DOC_URI); |
| 1115 | + String data = "<foobar/>"; |
| 1116 | + try { |
| 1117 | + connect.setRequestProperty("Authorization", "Basic " + credentials); |
| 1118 | + connect.setRequestMethod("PUT"); |
| 1119 | + connect.setDoOutput(true); |
| 1120 | + connect.setRequestProperty("ContentType", "application/xml"); |
| 1121 | + try (final Writer writer = new OutputStreamWriter(connect.getOutputStream(), UTF_8)) { |
| 1122 | + writer.write(data); |
| 1123 | + } |
| 1124 | + |
| 1125 | + connect.connect(); |
| 1126 | + final int r = connect.getResponseCode(); |
| 1127 | + assertEquals("doPut: Server returned response code " + r, HttpStatus.CREATED_201, r); |
| 1128 | + |
| 1129 | + // assert file content updated |
| 1130 | + getConnect.setRequestMethod("GET"); |
| 1131 | + getConnect.connect(); |
| 1132 | + |
| 1133 | + final int res_code = getConnect.getResponseCode(); |
| 1134 | + assertEquals("Server returned response code " + res_code, HttpStatus.OK_200, res_code); |
| 1135 | + |
| 1136 | + String response = readResponse(getConnect.getInputStream()); |
| 1137 | + |
| 1138 | + //readResponse is appending \r\n to each line that's why its added the expected content |
| 1139 | + assertEquals("Server returned document content " + response,"<foobar/>\r\n",response); |
| 1140 | + |
| 1141 | + } finally { |
| 1142 | + connect.disconnect(); |
| 1143 | + getConnect.disconnect(); |
| 1144 | + } |
| 1145 | + } |
| 1146 | + |
| 1147 | + @Test |
| 1148 | + public void doPostEncodedPath() throws IOException { |
| 1149 | + String DOC_URI = getServerUri() + XmldbURI.ROOT_COLLECTION + "/AéB/AéB.xml"; |
| 1150 | + final HttpURLConnection connect = getConnection(DOC_URI); |
| 1151 | + |
| 1152 | + String data = "<query xmlns=\"http://exist.sourceforge.net/NS/exist\">\n" + |
| 1153 | + " <text>\n" + |
| 1154 | + " //foo\n" + |
| 1155 | + " </text>\n" + |
| 1156 | + "</query>"; |
| 1157 | + try { |
| 1158 | + connect.setRequestProperty("Authorization", "Basic " + credentials); |
| 1159 | + connect.setRequestMethod("POST"); |
| 1160 | + connect.setDoOutput(true); |
| 1161 | + connect.setRequestProperty("Content-Type", "application/xml"); |
| 1162 | + try (final Writer writer = new OutputStreamWriter(connect.getOutputStream(), UTF_8)) { |
| 1163 | + writer.write(data); |
| 1164 | + } |
| 1165 | + |
| 1166 | + connect.connect(); |
| 1167 | + final int r = connect.getResponseCode(); |
| 1168 | + assertEquals("doPut: Server returned response code " + r, HttpStatus.OK_200, r); |
| 1169 | + |
| 1170 | + String response = readResponse(connect.getInputStream()); |
| 1171 | + |
| 1172 | + //readResponse is appending \r\n to each line that's why its added the expected content |
| 1173 | + assertTrue("Server returned " + response,response.contains("exist:hits=\"1\"")); |
| 1174 | + |
| 1175 | + } finally { |
| 1176 | + connect.disconnect(); |
| 1177 | + } |
| 1178 | + } |
| 1179 | + |
| 1180 | + @Test |
| 1181 | + public void doDeleteEncodedPath() throws IOException { |
| 1182 | + String DOC_URI = getServerUri() + XmldbURI.ROOT_COLLECTION + "/AéB/AéB.xml"; |
| 1183 | + final HttpURLConnection connect = getConnection(DOC_URI); |
| 1184 | + final HttpURLConnection getConnect = getConnection(DOC_URI); |
| 1185 | + |
| 1186 | + try { |
| 1187 | + connect.setRequestProperty("Authorization", "Basic " + credentials); |
| 1188 | + connect.setRequestMethod("DELETE"); |
| 1189 | + connect.setDoOutput(true); |
| 1190 | + |
| 1191 | + connect.connect(); |
| 1192 | + final int r = connect.getResponseCode(); |
| 1193 | + assertEquals("doPut: Server returned response code " + r, HttpStatus.OK_200, r); |
| 1194 | + |
| 1195 | + // assert file content updated |
| 1196 | + getConnect.setRequestMethod("GET"); |
| 1197 | + getConnect.connect(); |
| 1198 | + |
| 1199 | + |
| 1200 | + final int res_code = getConnect.getResponseCode(); |
| 1201 | + assertEquals("Server returned response code " + res_code, HttpStatus.NOT_FOUND_404, res_code); |
| 1202 | + |
| 1203 | + }finally { |
| 1204 | + connect.disconnect(); |
| 1205 | + getConnect.disconnect(); |
| 1206 | + } |
| 1207 | + } |
| 1208 | + |
1039 | 1209 | private void chmod(final String resourcePath, final String mode) throws IOException {
|
1040 | 1210 | final String uri = getCollectionUri() +"?_query=" + URLEncoder.encode(
|
1041 | 1211 | "sm:chmod(xs:anyURI('" + resourcePath + "'), '" + mode + "')",
|
|
0 commit comments