X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms%2Fsrc%2Forg%2Fargeo%2Fcms%2Finternal%2Fruntime%2FCmsAcrHttpHandler.java;h=5a42a3e383ec2d9435af424f7276f394e3f18623;hb=1d6840195189cbdbf632ca2800b6179d3b6349df;hp=11fc1a3667140ea5b444947cd83dab98112f1642;hpb=6832a0807e45e70c23b22598874807a3a9373475;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsAcrHttpHandler.java b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsAcrHttpHandler.java index 11fc1a366..5a42a3e38 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsAcrHttpHandler.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/runtime/CmsAcrHttpHandler.java @@ -2,7 +2,6 @@ package org.argeo.cms.internal.runtime; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.util.Collection; import java.util.Map; import java.util.Optional; @@ -14,76 +13,57 @@ import java.util.function.Consumer; import javax.xml.namespace.QName; import org.argeo.api.acr.Content; +import org.argeo.api.acr.ContentNotFoundException; import org.argeo.api.acr.ContentSession; import org.argeo.api.acr.DName; import org.argeo.api.acr.spi.ProvidedRepository; import org.argeo.api.cms.CmsConstants; -import org.argeo.cms.acr.ContentUtils; import org.argeo.cms.auth.RemoteAuthUtils; import org.argeo.cms.dav.DavDepth; -import org.argeo.cms.dav.DavMethod; +import org.argeo.cms.dav.DavHttpHandler; import org.argeo.cms.dav.DavPropfind; import org.argeo.cms.dav.DavResponse; -import org.argeo.cms.dav.DavXmlElement; -import org.argeo.cms.dav.MultiStatusWriter; import org.argeo.cms.internal.http.RemoteAuthHttpExchange; import org.argeo.util.StreamUtils; -import org.argeo.util.http.HttpMethod; import org.argeo.util.http.HttpResponseStatus; -import org.argeo.util.http.HttpServerUtils; import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; -public class CmsAcrHttpHandler implements HttpHandler { +/** A partial WebDav implementation based on ACR. */ +public class CmsAcrHttpHandler extends DavHttpHandler { private ProvidedRepository contentRepository; @Override - public void handle(HttpExchange exchange) throws IOException { - String method = exchange.getRequestMethod(); - if (DavMethod.PROPFIND.name().equals(method)) { - handlePROPFIND(exchange); - } else if (HttpMethod.GET.name().equals(method)) { - handleGET(exchange); - } else { - throw new IllegalArgumentException("Unsupported method " + method); + protected void handleGET(HttpExchange exchange, String path) throws IOException { + ContentSession session = RemoteAuthUtils.doAs(() -> contentRepository.get(), + new RemoteAuthHttpExchange(exchange)); + if (!session.exists(path)) // not found + throw new ContentNotFoundException(session, path); + Content content = session.get(path); + Optional size = content.get(DName.getcontentlength, Long.class); + try (InputStream in = content.open(InputStream.class)) { + exchange.sendResponseHeaders(HttpResponseStatus.OK.getCode(), size.orElse(0l)); + StreamUtils.copy(in, exchange.getResponseBody()); + } catch (IOException e) { + throw new RuntimeException("Cannot process " + path, e); } - } - protected void handlePROPFIND(HttpExchange exchange) throws IOException { - String relativePath = HttpServerUtils.relativize(exchange); - - DavDepth depth = DavDepth.fromHttpExchange(exchange); - if (depth == null) { - // default, as per http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND - depth = DavDepth.DEPTH_INFINITY; - } - + @Override + protected CompletableFuture handlePROPFIND(HttpExchange exchange, String path, DavPropfind davPropfind, + Consumer consumer) throws IOException { ContentSession session = RemoteAuthUtils.doAs(() -> contentRepository.get(), new RemoteAuthHttpExchange(exchange)); - - String path = ContentUtils.ROOT_SLASH + relativePath; - if (!session.exists(path)) {// not found - exchange.sendResponseHeaders(HttpResponseStatus.NOT_FOUND.getCode(), -1); - return; - } + if (!session.exists(path)) // not found + throw new ContentNotFoundException(session, path); Content content = session.get(path); CompletableFuture published = new CompletableFuture(); - - try (InputStream in = exchange.getRequestBody()) { - DavPropfind davPropfind = DavPropfind.load(depth, in); - MultiStatusWriter msWriter = new MultiStatusWriter(); - ForkJoinPool.commonPool().execute(() -> { - publishDavResponses(content, davPropfind, msWriter); - published.complete(null); - }); - exchange.sendResponseHeaders(HttpResponseStatus.MULTI_STATUS.getCode(), 0l); - try (OutputStream out = exchange.getResponseBody()) { - msWriter.process(session, out, published.minimalCompletionStage(), davPropfind.isPropname()); - } - } + ForkJoinPool.commonPool().execute(() -> { + publishDavResponses(content, davPropfind, consumer); + published.complete(null); + }); + return published; } protected void publishDavResponses(Content content, DavPropfind davPropfind, Consumer consumer) { @@ -114,7 +94,7 @@ public class CmsAcrHttpHandler implements HttpHandler { Object value = content.get(key); processMapEntry(davResponse, key, value); } - if (DavXmlElement.resourcetype.qName().equals(key)) { + if (DName.resourcetype.qName().equals(key)) { davResponse.getResourceTypes().addAll(content.getContentClasses()); } } @@ -152,20 +132,6 @@ public class CmsAcrHttpHandler implements HttpHandler { } - protected void handleGET(HttpExchange exchange) { - String relativePath = HttpServerUtils.relativize(exchange); - ContentSession session = RemoteAuthUtils.doAs(() -> contentRepository.get(), - new RemoteAuthHttpExchange(exchange)); - Content content = session.get(ContentUtils.ROOT_SLASH + relativePath); - Optional size = content.get(DName.getcontentlength, Long.class); - try (InputStream in = content.open(InputStream.class)) { - exchange.sendResponseHeaders(HttpResponseStatus.OK.getCode(), size.orElse(0l)); - StreamUtils.copy(in, exchange.getResponseBody()); - } catch (IOException e) { - throw new RuntimeException("Cannot process " + relativePath, e); - } - } - public void setContentRepository(ProvidedRepository contentRepository) { this.contentRepository = contentRepository; }