();
+ saIndexMap = new TreeMap<>();
for (StorageAreaInfo sa : saConfig.getStorageAreaInfo()) {
saIndexMap.put(sa.name(), sa.accessPoints().get(0));
}
@@ -92,7 +94,11 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
req.setAttribute(STORM_HOSTNAME_KEY, serviceConfig.getHostnames().get(0));
req.setAttribute(OIDC_ENABLED_KEY, oauthProperties.isEnableOidc());
- WebContext ctxt = new WebContext(req, resp, getServletContext(), req.getLocale());
+ final IWebExchange webExchange =
+ JakartaServletWebApplication.buildApplication(this.getServletContext())
+ .buildExchange(req, resp);
+
+ WebContext ctxt = new WebContext(webExchange, req.getLocale());
engine.process(SA_INDEX_PAGE_NAME, ctxt, resp.getWriter());
}
diff --git a/src/main/java/org/italiangrid/storm/webdav/server/servlet/SciTagFilter.java b/src/main/java/org/italiangrid/storm/webdav/server/servlet/SciTagFilter.java
index f01c0af1..26b0c710 100644
--- a/src/main/java/org/italiangrid/storm/webdav/server/servlet/SciTagFilter.java
+++ b/src/main/java/org/italiangrid/storm/webdav/server/servlet/SciTagFilter.java
@@ -18,12 +18,12 @@
import java.io.IOException;
import java.util.Optional;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
import org.italiangrid.storm.webdav.scitag.SciTag;
import org.italiangrid.storm.webdav.tpc.TransferConstants;
diff --git a/src/main/java/org/italiangrid/storm/webdav/server/servlet/StoRMServlet.java b/src/main/java/org/italiangrid/storm/webdav/server/servlet/StoRMServlet.java
index 68145aa7..b2e009f8 100644
--- a/src/main/java/org/italiangrid/storm/webdav/server/servlet/StoRMServlet.java
+++ b/src/main/java/org/italiangrid/storm/webdav/server/servlet/StoRMServlet.java
@@ -15,78 +15,146 @@
*/
package org.italiangrid.storm.webdav.server.servlet;
-import java.io.File;
+import java.io.FileNotFoundException;
import java.io.IOException;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.servlet.DefaultServlet;
-import org.eclipse.jetty.util.resource.Resource;
+import jakarta.servlet.RequestDispatcher;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.ee10.servlet.ResourceServlet;
+import org.eclipse.jetty.ee10.servlet.ServletContextRequest;
+import org.eclipse.jetty.ee10.servlet.ServletContextResponse;
+import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.http.content.HttpContent;
import org.italiangrid.storm.webdav.config.OAuthProperties;
import org.italiangrid.storm.webdav.config.ServiceConfigurationProperties;
import org.italiangrid.storm.webdav.server.PathResolver;
-import org.italiangrid.storm.webdav.server.servlet.resource.StormResourceService;
-import org.italiangrid.storm.webdav.server.servlet.resource.StormResourceWrapper;
+import org.italiangrid.storm.webdav.server.servlet.resource.StoRMResourceHttpContentFactory;
import org.thymeleaf.TemplateEngine;
+import org.eclipse.jetty.util.URIUtil;
+import org.italiangrid.storm.webdav.scitag.SciTag;
+import org.italiangrid.storm.webdav.scitag.SciTagTransfer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-public class StoRMServlet extends DefaultServlet {
+public class StoRMServlet extends ResourceServlet {
+ public static final Logger LOG = LoggerFactory.getLogger(StoRMServlet.class);
/**
*
*/
private static final long serialVersionUID = 4204673943980786498L;
- final PathResolver pathResolver;
- final TemplateEngine templateEngine;
- final ServiceConfigurationProperties serviceConfig;
- final OAuthProperties oauthProperties;
- final StormResourceService resourceService;
+ final transient PathResolver pathResolver;
+ final transient TemplateEngine templateEngine;
+ final transient ServiceConfigurationProperties serviceConfig;
+ final transient OAuthProperties oauthProperties;
public StoRMServlet(OAuthProperties oauthP, ServiceConfigurationProperties serviceConfig,
- PathResolver resolver, TemplateEngine engine, StormResourceService rs) {
- super(rs);
+ PathResolver resolver, TemplateEngine engine) {
+ super();
oauthProperties = oauthP;
- resourceService = rs;
pathResolver = resolver;
templateEngine = engine;
this.serviceConfig = serviceConfig;
}
@Override
- public Resource getResource(String pathInContext) {
-
- String resolvedPath = pathResolver.resolvePath(pathInContext);
-
- if (resolvedPath == null) {
- return null;
- }
+ public void init() throws ServletException {
+ super.init();
+ this.getResourceService()
+ .setHttpContentFactory(new StoRMResourceHttpContentFactory(null, MimeTypes.DEFAULTS,
+ oauthProperties, serviceConfig, pathResolver, templateEngine));
+ }
- File f = new File(resolvedPath);
+ // Similar to getInitBoolean of
+ // https://github.com/jetty/jetty.project/blob/jetty-12.0.x/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ResourceServlet.java
+ private boolean getInitBooleanStoRM(String name, boolean defaultValue) {
+ String value = getInitParameter(name);
+ if (value == null || value.isEmpty())
+ return defaultValue;
+ return (value.startsWith("t") || value.startsWith("T") || value.startsWith("y")
+ || value.startsWith("Y") || value.startsWith("1"));
+ }
- if (!f.exists()) {
- return null;
+ @Override
+ protected String getEncodedPathInContext(HttpServletRequest request, boolean included) {
+ String servletPath = null;
+ String pathInfo = null;
+
+ if (included) {
+ servletPath = getInitBooleanStoRM("pathInfoOnly", false) ? "/"
+ : (String) request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
+ pathInfo = (String) request.getAttribute(RequestDispatcher.INCLUDE_PATH_INFO);
+ if (servletPath == null) {
+ servletPath = request.getServletPath();
+ pathInfo = request.getPathInfo();
+ }
+ } else {
+ servletPath = getInitBooleanStoRM("pathInfoOnly", false) ? "/" : request.getServletPath();
+ pathInfo = request.getPathInfo();
}
- return new StormResourceWrapper(oauthProperties, serviceConfig, templateEngine,
- Resource.newResource(f));
-
+ return URIUtil.addPaths(servletPath, pathInfo);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
- resourceService.doGet(request, response);
+ SciTag scitag = (SciTag) request.getAttribute(SciTag.SCITAG_ATTRIBUTE);
+ SciTagTransfer scitagTransfer = null;
+ if (scitag != null) {
+ scitagTransfer = new SciTagTransfer(scitag, request.getLocalAddr(), request.getLocalPort(),
+ request.getRemoteAddr(), request.getRemotePort());
+ scitagTransfer.writeStart();
+ }
+ if (request.getHeader("Range") != null) {
+ ServletContextRequest servletContextRequest =
+ ServletContextRequest.getServletContextRequest(request);
+ ServletContextResponse servletContextResponse =
+ servletContextRequest.getServletContextResponse();
+ super.doGet(request, servletContextResponse.getServletApiResponse());
+ } else {
+ super.doGet(request, response);
+ }
+ if (scitagTransfer != null) {
+ scitagTransfer.writeEnd();
+ }
}
@Override
protected void doHead(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
- resourceService.doHead(request, response);
+ final boolean included = request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) != null;
+ final String pathInContext = getEncodedPathInContext(request, included);
+
+ final HttpContent content =
+ getResourceService().getHttpContentFactory().getContent(pathInContext);
+
+ if (content == null || !content.getResource().exists()) {
+
+ if (included) {
+ throw new FileNotFoundException("!" + pathInContext);
+ }
+
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ } else {
+ response.setHeader(HttpHeader.LAST_MODIFIED.asString(), content.getLastModified().getValue());
+ if (content.getContentLength() != null) {
+ response.setHeader(HttpHeader.CONTENT_LENGTH.asString(),
+ content.getContentLength().getValue());
+ }
+ if (content.getContentType() != null) {
+ response.setHeader(HttpHeader.CONTENT_TYPE.asString(), content.getContentType().getValue());
+ }
+ response.setHeader(HttpHeader.ACCEPT_RANGES.asString(), "bytes");
+ }
}
-
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
diff --git a/src/main/java/org/italiangrid/storm/webdav/server/servlet/resource/StoRMResourceHttpContentFactory.java b/src/main/java/org/italiangrid/storm/webdav/server/servlet/resource/StoRMResourceHttpContentFactory.java
new file mode 100644
index 00000000..b2293383
--- /dev/null
+++ b/src/main/java/org/italiangrid/storm/webdav/server/servlet/resource/StoRMResourceHttpContentFactory.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) Istituto Nazionale di Fisica Nucleare, 2014-2023.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.italiangrid.storm.webdav.server.servlet.resource;
+
+import java.io.File;
+import java.net.URI;
+
+import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.http.content.HttpContent;
+import org.eclipse.jetty.http.content.ResourceHttpContent;
+import org.eclipse.jetty.http.content.ResourceHttpContentFactory;
+import org.eclipse.jetty.util.resource.PathResourceFactory;
+import org.eclipse.jetty.util.resource.Resource;
+import org.italiangrid.storm.webdav.config.OAuthProperties;
+import org.italiangrid.storm.webdav.config.ServiceConfigurationProperties;
+import org.italiangrid.storm.webdav.server.PathResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.thymeleaf.TemplateEngine;
+
+public class StoRMResourceHttpContentFactory extends ResourceHttpContentFactory {
+ public static final Logger LOG = LoggerFactory.getLogger(StoRMResourceHttpContentFactory.class);
+ final PathResolver pathResolver;
+ final TemplateEngine templateEngine;
+ final ServiceConfigurationProperties serviceConfig;
+ final OAuthProperties oauthProperties;
+ MimeTypes mimeTypes;
+
+ public StoRMResourceHttpContentFactory(Resource baseResource, MimeTypes mimeTypes,
+ OAuthProperties oauthP, ServiceConfigurationProperties serviceConfig, PathResolver resolver,
+ TemplateEngine engine) {
+ super(baseResource, mimeTypes);
+ this.mimeTypes = mimeTypes;
+ pathResolver = resolver;
+ oauthProperties = oauthP;
+ templateEngine = engine;
+ this.serviceConfig = serviceConfig;
+ }
+
+ @Override
+ public HttpContent getContent(String pathInContext) {
+
+ String resolvedPath = pathResolver.resolvePath(pathInContext);
+ LOG.warn("pathInContext: {}, resolvedPath: {}", pathInContext, resolvedPath);
+
+ if (resolvedPath == null) {
+ return null;
+ }
+
+ File f = new File(resolvedPath);
+
+ if (!f.exists()) {
+ LOG.warn("File {} do not exist", resolvedPath);
+ return null;
+ }
+
+ PathResourceFactory pathResourceFactory = new PathResourceFactory();
+ try {
+ if (f.isDirectory()) {
+ StormResourceWrapper resource =
+ new StormResourceWrapper(oauthProperties, serviceConfig, templateEngine,
+ pathResourceFactory.newResource(new URI("file:" + resolvedPath)), pathInContext);
+ return new ResourceHttpContent(resource, "text/html");
+ } else {
+ return new ResourceHttpContent(
+ pathResourceFactory.newResource(new URI("file:" + resolvedPath)),
+ mimeTypes.getMimeByExtension(pathInContext));
+ }
+ } catch (Exception e) {
+ LOG.warn("PathResourceFactory exception: {}", e.getMessage());
+ }
+
+ return null;
+ }
+}
diff --git a/src/main/java/org/italiangrid/storm/webdav/server/servlet/resource/StormFsResourceView.java b/src/main/java/org/italiangrid/storm/webdav/server/servlet/resource/StormFsResourceView.java
index 2add60c2..98fc35ce 100644
--- a/src/main/java/org/italiangrid/storm/webdav/server/servlet/resource/StormFsResourceView.java
+++ b/src/main/java/org/italiangrid/storm/webdav/server/servlet/resource/StormFsResourceView.java
@@ -33,18 +33,18 @@ public class StormFsResourceView {
private StormFsResourceView(Builder b) {
if (b.isDirectory && !b.name.endsWith("/")) {
- this.name = b.name +"/";
+ this.name = b.name + "/";
} else {
this.name = b.name;
}
-
+
this.isDirectory = b.isDirectory;
this.path = b.path;
this.sizeInBytes = b.sizeInBytes;
this.lastModificationTime = b.lastModificationTime;
this.creationTime = b.creationTime;
-
-
+
+
}
public String getName() {
@@ -80,6 +80,7 @@ public Date getCreationTime() {
public static Builder builder() {
return new Builder();
}
+
public static class Builder {
String name;
boolean isDirectory;
diff --git a/src/main/java/org/italiangrid/storm/webdav/server/servlet/resource/StormResourceService.java b/src/main/java/org/italiangrid/storm/webdav/server/servlet/resource/StormResourceService.java
deleted file mode 100644
index aa606090..00000000
--- a/src/main/java/org/italiangrid/storm/webdav/server/servlet/resource/StormResourceService.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- * Copyright (c) Istituto Nazionale di Fisica Nucleare, 2014-2023.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.italiangrid.storm.webdav.server.servlet.resource;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-import javax.servlet.RequestDispatcher;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.http.HttpContent;
-import org.eclipse.jetty.server.ResourceService;
-import org.eclipse.jetty.util.URIUtil;
-import org.italiangrid.storm.webdav.scitag.SciTag;
-import org.italiangrid.storm.webdav.scitag.SciTagTransfer;
-
-public class StormResourceService extends ResourceService {
-
- private String pathInContext(HttpServletRequest request) {
- String servletPath = null;
- String pathInfo = null;
-
- boolean included = request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) != null;
-
- if (included) {
- servletPath = isPathInfoOnly() ? "/"
- : (String) request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
- pathInfo = (String) request.getAttribute(RequestDispatcher.INCLUDE_PATH_INFO);
- if (servletPath == null) {
- servletPath = request.getServletPath();
- pathInfo = request.getPathInfo();
- }
- } else {
- servletPath = isPathInfoOnly() ? "/" : request.getServletPath();
- pathInfo = request.getPathInfo();
- }
-
- return URIUtil.addPaths(servletPath, pathInfo);
- }
-
- @Override
- public boolean doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- SciTag scitag = (SciTag) request.getAttribute(SciTag.SCITAG_ATTRIBUTE);
- SciTagTransfer scitagTransfer = null;
- if (scitag != null) {
- scitagTransfer = new SciTagTransfer(scitag, request.getLocalAddr(), request.getLocalPort(),
- request.getRemoteAddr(), request.getRemotePort());
- scitagTransfer.writeStart();
- }
- boolean result = super.doGet(request, response);
- if (scitagTransfer != null) {
- scitagTransfer.writeEnd();
- }
- return result;
- }
-
- public boolean doHead(HttpServletRequest request, HttpServletResponse response)
- throws IOException {
-
- final boolean included = request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) != null;
- final String pathInContext = pathInContext(request);
-
- final HttpContent content =
- getContentFactory().getContent(pathInContext, response.getBufferSize());
-
- if (content == null || !content.getResource().exists()) {
-
- if (included) {
- throw new FileNotFoundException("!" + pathInContext);
- }
-
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
- return response.isCommitted();
- }
-
- putHeaders(response, content, content.getContentLengthValue());
- return true;
- }
-
-}
diff --git a/src/main/java/org/italiangrid/storm/webdav/server/servlet/resource/StormResourceWrapper.java b/src/main/java/org/italiangrid/storm/webdav/server/servlet/resource/StormResourceWrapper.java
index 73a030e9..b6b8da0c 100644
--- a/src/main/java/org/italiangrid/storm/webdav/server/servlet/resource/StormResourceWrapper.java
+++ b/src/main/java/org/italiangrid/storm/webdav/server/servlet/resource/StormResourceWrapper.java
@@ -15,15 +15,15 @@
*/
package org.italiangrid.storm.webdav.server.servlet.resource;
-import java.io.File;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.nio.channels.ReadableByteChannel;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.time.Instant;
import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
@@ -45,40 +45,45 @@ public class StormResourceWrapper extends Resource {
final TemplateEngine engine;
final OAuthProperties oauthProperties;
final ServiceConfigurationProperties serviceConfig;
+ final String pathInContext;
public StormResourceWrapper(OAuthProperties oauth, ServiceConfigurationProperties serviceConfig,
- TemplateEngine engine, Resource delegate) {
+ TemplateEngine engine, Resource delegate, String pathInContext) {
this.oauthProperties = oauth;
this.engine = engine;
this.delegate = delegate;
this.serviceConfig = serviceConfig;
+ this.pathInContext = pathInContext;
}
+ // Adapted from
+ // https://github.com/jetty/jetty.project/blob/jetty-12.0.x/jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/ResourceListing.java
/**
- * Encode any characters that could break the URI string in an HREF. Such as ">Link
+ *
+ * Encode any characters that could break the URI string in an HREF.
+ *
*
+ *
+ * Such as: {@code Link}
+ *
+ *
* The above example would parse incorrectly on various browsers as the "<" or '"' characters
* would end the href attribute value string prematurely.
+ *
*
* @param raw the raw text to encode.
* @return the defanged text.
*/
private static String hrefEncodeURI(String raw) {
-
StringBuffer buf = null;
- loop: for (int i = 0; i < raw.length(); i++) {
+ for (int i = 0; i < raw.length(); i++) {
char c = raw.charAt(i);
- switch (c) {
- case '\'':
- case '"':
- case '<':
- case '>':
- buf = new StringBuffer(raw.length() << 1);
- break loop;
+ if (c == '\'' || c == '"' || c == '<' || c == '>') {
+ buf = new StringBuffer(raw.length() << 1);
+ break;
}
}
if (buf == null)
@@ -87,39 +92,21 @@ private static String hrefEncodeURI(String raw) {
for (int i = 0; i < raw.length(); i++) {
char c = raw.charAt(i);
switch (c) {
- case '"':
- buf.append("%22");
- continue;
- case '\'':
- buf.append("%27");
- continue;
- case '<':
- buf.append("%3C");
- continue;
- case '>':
- buf.append("%3E");
- continue;
- default:
- buf.append(c);
- continue;
+ case '"' -> buf.append("%22");
+ case '\'' -> buf.append("%27");
+ case '<' -> buf.append("%3C");
+ case '>' -> buf.append("%3E");
+ default -> buf.append(c);
}
}
return buf.toString();
}
-
- @Override
- public String getListHTML(String base, boolean parent, String query) throws IOException {
-
+ public String getListHTML(String base) {
base = URIUtil.canonicalPath(base);
- if (base == null || !isDirectory())
- return null;
- String[] rawListing = list();
- if (rawListing == null) {
- return null;
- }
+ List rawListing = list();
Context context = new Context();
@@ -139,17 +126,16 @@ public String getListHTML(String base, boolean parent, String query) throws IOEx
String parentDir = URIUtil.addPaths(encodedBase, "../");
- Arrays.sort(rawListing);
+ Collections.sort(rawListing, (a, b) -> a.getFileName().compareTo(b.getFileName()));
List resources = new ArrayList<>();
- for (String l : rawListing) {
- Resource r = addPath(l);
+ for (Resource r : rawListing) {
resources.add(StormFsResourceView.builder()
- .withName(l)
- .withPath(URIUtil.addEncodedPaths(encodedBase, URIUtil.encodePath(l)))
+ .withName(r.getFileName())
+ .withPath(URIUtil.addEncodedPaths(encodedBase, r.getFileName()))
.withIsDirectory(r.isDirectory())
- .withLastModificationTime(new Date(r.lastModified()))
+ .withLastModificationTime(Date.from(r.lastModified()))
.withSizeInBytes(r.length())
.build());
}
@@ -160,18 +146,6 @@ public String getListHTML(String base, boolean parent, String query) throws IOEx
return engine.process(JETTY_DIR_TEMPLATE, context);
}
- @Override
- public boolean isContainedIn(Resource r) throws MalformedURLException {
-
- return delegate.isContainedIn(r);
- }
-
- @Override
- public void close() {
-
- delegate.close();
- }
-
@Override
public boolean exists() {
return delegate.exists();
@@ -179,11 +153,17 @@ public boolean exists() {
@Override
public boolean isDirectory() {
- return delegate.isDirectory();
+ // We must lie otherwise Jetty uses its non-overridable directory listing
+ return false;
+ }
+
+ @Override
+ public boolean isReadable() {
+ return delegate.isReadable();
}
@Override
- public long lastModified() {
+ public Instant lastModified() {
return delegate.lastModified();
}
@@ -192,15 +172,14 @@ public long length() {
return delegate.length();
}
- @SuppressWarnings("deprecation")
@Override
- public URL getURL() {
- return delegate.getURL();
+ public URI getURI() {
+ return delegate.getURI();
}
@Override
- public File getFile() throws IOException {
- return delegate.getFile();
+ public String getFileName() {
+ return delegate.getFileName();
}
@Override
@@ -209,85 +188,23 @@ public String getName() {
}
@Override
- public InputStream getInputStream() throws IOException {
- return delegate.getInputStream();
+ public Path getPath() {
+ // We must lie so Jetty uses our overrided newInputStream
+ return null;
}
@Override
- public ReadableByteChannel getReadableByteChannel() throws IOException {
- return delegate.getReadableByteChannel();
+ public InputStream newInputStream() throws IOException {
+ return new ByteArrayInputStream(getListHTML(pathInContext).getBytes(StandardCharsets.UTF_8));
}
@Override
- public boolean delete() throws SecurityException {
- return delegate.delete();
- }
-
- @Override
- public boolean renameTo(Resource dest) throws SecurityException {
- return delegate.renameTo(dest);
- }
-
- @Override
- public String[] list() {
+ public List list() {
return delegate.list();
}
@Override
- public Resource addPath(String path) throws IOException {
- return delegate.addPath(path);
- }
-
- @Override
- public void writeTo(OutputStream out, long start, long count) throws IOException {
-
- try (InputStream in = getInputStream()) {
- if (start > 0) {
- long n = in.skip(start);
- if (n < start) {
- throw new IOException("Skipped " + start + " bytes but read " + n);
- }
- }
- if (count < 0) {
- internalCopy(in, out);
- } else {
- internalCopy(in, out, count);
- }
- }
-
- }
-
- private void internalCopy(InputStream in, OutputStream out, long byteCount) throws IOException {
-
- int bufferSize = serviceConfig.getBuffer().getFileBufferSizeBytes();
- byte[] buffer = new byte[bufferSize];
- int len = bufferSize;
-
- if (byteCount >= 0) {
- while (byteCount > 0) {
- int max = byteCount < bufferSize ? (int) byteCount : bufferSize;
- len = in.read(buffer, 0, max);
-
- if (len == -1)
- break;
-
- byteCount -= len;
- out.write(buffer, 0, len);
- }
- } else {
- while (true) {
- len = in.read(buffer, 0, bufferSize);
- if (len < 0)
- break;
- out.write(buffer, 0, len);
- }
- }
-
- }
-
- private void internalCopy(InputStream in, OutputStream out) throws IOException {
- internalCopy(in, out, -1);
+ public Resource resolve(String subUriPath) {
+ return delegate.resolve(subUriPath);
}
-
-
}
diff --git a/src/main/java/org/italiangrid/storm/webdav/server/tracing/LogbackAccessAuthnInfoFilter.java b/src/main/java/org/italiangrid/storm/webdav/server/tracing/LogbackAccessAuthnInfoFilter.java
index 4e62dc3f..af101132 100644
--- a/src/main/java/org/italiangrid/storm/webdav/server/tracing/LogbackAccessAuthnInfoFilter.java
+++ b/src/main/java/org/italiangrid/storm/webdav/server/tracing/LogbackAccessAuthnInfoFilter.java
@@ -17,12 +17,12 @@
import java.io.IOException;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
import org.italiangrid.storm.webdav.authn.PrincipalHelper;
import org.springframework.security.core.Authentication;
@@ -37,6 +37,7 @@ public class LogbackAccessAuthnInfoFilter implements Filter {
public LogbackAccessAuthnInfoFilter(PrincipalHelper principalHelper) {
this.helper = principalHelper;
}
+
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
diff --git a/src/main/java/org/italiangrid/storm/webdav/server/tracing/RequestIdFilter.java b/src/main/java/org/italiangrid/storm/webdav/server/tracing/RequestIdFilter.java
index 023ea6a1..87411f83 100644
--- a/src/main/java/org/italiangrid/storm/webdav/server/tracing/RequestIdFilter.java
+++ b/src/main/java/org/italiangrid/storm/webdav/server/tracing/RequestIdFilter.java
@@ -17,11 +17,11 @@
import java.io.IOException;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
import org.slf4j.MDC;
@@ -32,11 +32,11 @@ public class RequestIdFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
-
+
RequestIdHolder.setRandomId();
request.setAttribute(REQUEST_ID_ATTRIBUTE_NAME, RequestIdHolder.getRequestId());
MDC.put(REQUEST_ID_ATTRIBUTE_NAME, RequestIdHolder.getRequestId());
-
+
try {
chain.doFilter(request, response);
} finally {
@@ -44,6 +44,6 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
MDC.clear();
}
}
-
+
}
diff --git a/src/main/java/org/italiangrid/storm/webdav/server/util/JettyErrorPageHandler.java b/src/main/java/org/italiangrid/storm/webdav/server/util/JettyErrorPageHandler.java
deleted file mode 100644
index 8e71a188..00000000
--- a/src/main/java/org/italiangrid/storm/webdav/server/util/JettyErrorPageHandler.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Copyright (c) Istituto Nazionale di Fisica Nucleare, 2014-2023.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.italiangrid.storm.webdav.server.util;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
-
-public class JettyErrorPageHandler extends ErrorPageErrorHandler {
-
- private static final Set HANDLED_HTTP_METHODS =
- new HashSet<>(Arrays.asList("GET", "POST", "HEAD"));
-
- @Override
- public boolean errorPageForMethod(String method) {
- return true;
- }
-
- @Override
- public void handle(String target, Request baseRequest, HttpServletRequest request,
- HttpServletResponse response) throws IOException {
- if (!HANDLED_HTTP_METHODS.contains(baseRequest.getMethod())) {
- baseRequest.setMethod("GET");
- }
- super.doError(target, baseRequest, request, response);
- }
-
-}
diff --git a/src/main/java/org/italiangrid/storm/webdav/spring/AppConfig.java b/src/main/java/org/italiangrid/storm/webdav/spring/AppConfig.java
index 08b344a8..900075c1 100644
--- a/src/main/java/org/italiangrid/storm/webdav/spring/AppConfig.java
+++ b/src/main/java/org/italiangrid/storm/webdav/spring/AppConfig.java
@@ -26,6 +26,7 @@
import java.security.Security;
import java.security.cert.CertificateException;
import java.time.Clock;
+import java.util.HashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -37,16 +38,23 @@
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.config.ConnectionConfig;
-import org.apache.http.config.Registry;
-import org.apache.http.config.RegistryBuilder;
-import org.apache.http.conn.HttpClientConnectionManager;
-import org.apache.http.conn.socket.ConnectionSocketFactory;
-import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.config.ConnectionConfig;
+import org.apache.hc.core5.http.config.Http1Config;
+import org.apache.hc.core5.http.config.Registry;
+import org.apache.hc.core5.http.config.RegistryBuilder;
+import org.apache.hc.core5.http.io.HttpConnectionFactory;
+import org.apache.hc.client5.http.io.HttpClientConnectionManager;
+import org.apache.hc.client5.http.io.ManagedHttpClientConnection;
+import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
+import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory;
+import org.apache.hc.client5.http.impl.DefaultRedirectStrategy;
+import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.HttpClients;
+import org.apache.hc.client5.http.impl.io.ManagedHttpClientConnectionFactory;
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
+import org.apache.hc.client5.http.impl.routing.DefaultRoutePlanner;
import org.conscrypt.OpenSSLProvider;
import org.italiangrid.storm.webdav.authn.PrincipalHelper;
import org.italiangrid.storm.webdav.authz.AuthorizationPolicyService;
@@ -92,7 +100,6 @@
import org.italiangrid.storm.webdav.tpc.TpcPlainConnectionSocketFactory;
import org.italiangrid.storm.webdav.tpc.TpcSSLConnectionSocketFactory;
import org.italiangrid.storm.webdav.tpc.TransferConstants;
-import org.italiangrid.storm.webdav.tpc.http.SuperLaxRedirectStrategy;
import org.italiangrid.voms.util.CertificateValidatorBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -107,6 +114,9 @@
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.server.resource.web.BearerTokenResolver;
+import org.springframework.session.MapSession;
+import org.springframework.session.MapSessionRepository;
+import org.springframework.session.SessionRepository;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.health.HealthCheckRegistry;
@@ -239,6 +249,17 @@ ScheduledExecutorService tpcProgressReportEs(ThirdPartyCopyProperties props) {
HttpClientConnectionManager tpcClientConnectionManager(ThirdPartyCopyProperties props,
ServiceConfiguration conf) throws KeyStoreException, CertificateException, IOException,
NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException {
+
+ Http1Config customHttpConfig =
+ Http1Config.custom().setBufferSize(props.getHttpClientSocketBufferSize()).build();
+ HttpConnectionFactory connectionFactory =
+ ManagedHttpClientConnectionFactory.builder().http1Config(customHttpConfig).build();
+
+ ConnectionConfig connectionConfig = ConnectionConfig.custom()
+ .setSocketTimeout(props.getTimeoutInSecs(), TimeUnit.SECONDS)
+ .setConnectTimeout(props.getTimeoutInSecs(), TimeUnit.SECONDS)
+ .build();
+
PEMCredential serviceCredential = serviceCredential(conf);
SSLTrustManager tm = new SSLTrustManager(canlCertChainValidator(conf));
@@ -272,9 +293,11 @@ HttpClientConnectionManager tpcClientConnectionManager(ThirdPartyCopyProperties
.register(TransferConstants.DAVS, tlsSf)
.build();
- PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(r);
- cm.setMaxTotal(props.getMaxConnections());
+ PoolingHttpClientConnectionManager cm =
+ new PoolingHttpClientConnectionManager(r, connectionFactory);
+ cm.setDefaultConnectionConfig(connectionConfig);
cm.setDefaultMaxPerRoute(props.getMaxConnectionsPerRoute());
+ cm.setMaxTotal(props.getMaxConnections());
return cm;
}
@@ -282,29 +305,25 @@ HttpClientConnectionManager tpcClientConnectionManager(ThirdPartyCopyProperties
CloseableHttpClient transferClient(ThirdPartyCopyProperties props,
@Qualifier("tpcConnectionManager") HttpClientConnectionManager cm) {
- ConnectionConfig connectionConfig =
- ConnectionConfig.custom().setBufferSize(props.getHttpClientSocketBufferSize()).build();
-
- int timeoutMsec = (int) TimeUnit.SECONDS.toMillis(props.getTimeoutInSecs());
RequestConfig config = RequestConfig.custom()
.setExpectContinueEnabled(false)
- .setConnectTimeout(timeoutMsec)
- .setConnectionRequestTimeout(timeoutMsec)
- .setSocketTimeout(timeoutMsec)
+ .setConnectionRequestTimeout(props.getTimeoutInSecs(), TimeUnit.SECONDS)
.build();
return HttpClients.custom()
.setConnectionManager(cm)
- .setDefaultConnectionConfig(connectionConfig)
+ .disableRedirectHandling()
+ .addExecInterceptorFirst("RemoveAuthorizationHeader",
+ new RedirectExec(new DefaultRoutePlanner(DefaultSchemePortResolver.INSTANCE),
+ DefaultRedirectStrategy.INSTANCE))
.setDefaultRequestConfig(config)
- .setRedirectStrategy(SuperLaxRedirectStrategy.INSTANCE)
.build();
}
@Bean
@ConditionalOnProperty(name = "oauth.enable-oidc", havingValue = "true")
- ClientRegistrationRepository clientRegistrationRepository(
- OAuth2ClientProperties clientProperties, OAuthProperties props, ExecutorService executor) {
+ ClientRegistrationRepository clientRegistrationRepository(OAuth2ClientProperties clientProperties,
+ OAuthProperties props, ExecutorService executor) {
ClientRegistrationCacheLoader loader =
@@ -443,6 +462,13 @@ PrincipalHelper principalHelper(ServiceConfigurationProperties config)
throws MalformedURLException {
return new PrincipalHelper(config);
}
+
+ @Bean
+ @ConditionalOnProperty(name = "spring.session.store-type", havingValue = "none")
+ public SessionRepository sessionRepository() {
+ return new MapSessionRepository(new HashMap<>());
+ }
+
}
diff --git a/src/main/java/org/italiangrid/storm/webdav/spring/RedirectExec.java b/src/main/java/org/italiangrid/storm/webdav/spring/RedirectExec.java
new file mode 100644
index 00000000..12b4306e
--- /dev/null
+++ b/src/main/java/org/italiangrid/storm/webdav/spring/RedirectExec.java
@@ -0,0 +1,230 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+package org.italiangrid.storm.webdav.spring;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.Objects;
+
+import org.apache.hc.client5.http.CircularRedirectException;
+import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.RedirectException;
+import org.apache.hc.client5.http.auth.AuthExchange;
+import org.apache.hc.client5.http.classic.ExecChain;
+import org.apache.hc.client5.http.classic.ExecChainHandler;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.client5.http.protocol.RedirectLocations;
+import org.apache.hc.client5.http.protocol.RedirectStrategy;
+import org.apache.hc.client5.http.routing.HttpRoutePlanner;
+import org.apache.hc.client5.http.utils.URIUtils;
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.Method;
+import org.apache.hc.core5.http.ProtocolException;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
+import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
+import org.apache.hc.core5.util.Args;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Request execution handler in the classic request execution chain
+ * responsible for handling of request redirects.
+ *
+ * Further responsibilities such as communication with the opposite
+ * endpoint is delegated to the next executor in the request execution
+ * chain.
+ *
+ *
+ * @since 4.3
+ */
+// Copied from https://github.com/apache/httpcomponents-client/blob/master/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/RedirectExec.java
+// Added the drop of Authorization header
+@Contract(threading = ThreadingBehavior.STATELESS)
+public final class RedirectExec implements ExecChainHandler {
+
+ private static final Logger LOG = LoggerFactory.getLogger(RedirectExec.class);
+
+ private final RedirectStrategy redirectStrategy;
+ private final HttpRoutePlanner routePlanner;
+
+ public RedirectExec(
+ final HttpRoutePlanner routePlanner,
+ final RedirectStrategy redirectStrategy) {
+ super();
+ Args.notNull(routePlanner, "HTTP route planner");
+ Args.notNull(redirectStrategy, "HTTP redirect strategy");
+ this.routePlanner = routePlanner;
+ this.redirectStrategy = redirectStrategy;
+ }
+
+ @Override
+ public ClassicHttpResponse execute(
+ final ClassicHttpRequest request,
+ final ExecChain.Scope scope,
+ final ExecChain chain) throws IOException, HttpException {
+ Args.notNull(request, "HTTP request");
+ Args.notNull(scope, "Scope");
+
+ final HttpClientContext context = scope.clientContext;
+ context.setRedirectLocations(null);
+
+ final RequestConfig config = context.getRequestConfigOrDefault();
+ final int maxRedirects = config.getMaxRedirects() > 0 ? config.getMaxRedirects() : 50;
+ ClassicHttpRequest currentRequest = request;
+ ExecChain.Scope currentScope = scope;
+ for (int redirectCount = 0;;) {
+ final String exchangeId = currentScope.exchangeId;
+ final ClassicHttpResponse response = chain.proceed(currentRequest, currentScope);
+ try {
+ if (config.isRedirectsEnabled() && this.redirectStrategy.isRedirected(request, response, context)) {
+ final HttpEntity requestEntity = request.getEntity();
+ // This is the only modification
+ scope.originalRequest.removeHeaders("Authorization");
+ if (requestEntity != null && !requestEntity.isRepeatable()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("{} cannot redirect non-repeatable request", exchangeId);
+ }
+ return response;
+ }
+ if (redirectCount >= maxRedirects) {
+ throw new RedirectException("Maximum redirects (" + maxRedirects + ") exceeded");
+ }
+ redirectCount++;
+
+ final URI redirectUri = this.redirectStrategy.getLocationURI(currentRequest, response, context);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("{} redirect requested to location '{}'", exchangeId, redirectUri);
+ }
+
+ final HttpHost newTarget = URIUtils.extractHost(redirectUri);
+ if (newTarget == null) {
+ throw new ProtocolException("Redirect URI does not specify a valid host name: " +
+ redirectUri);
+ }
+
+ final RedirectLocations redirectLocations = context.getRedirectLocations();
+ if (!config.isCircularRedirectsAllowed()) {
+ if (redirectLocations.contains(redirectUri)) {
+ throw new CircularRedirectException("Circular redirect to '" + redirectUri + "'");
+ }
+ }
+ redirectLocations.add(redirectUri);
+
+ final int statusCode = response.getCode();
+ final ClassicRequestBuilder redirectBuilder;
+ switch (statusCode) {
+ case HttpStatus.SC_MOVED_PERMANENTLY:
+ case HttpStatus.SC_MOVED_TEMPORARILY:
+ if (Method.POST.isSame(request.getMethod())) {
+ redirectBuilder = ClassicRequestBuilder.get();
+ } else {
+ redirectBuilder = ClassicRequestBuilder.copy(currentScope.originalRequest);
+ }
+ break;
+ case HttpStatus.SC_SEE_OTHER:
+ if (!Method.GET.isSame(request.getMethod()) && !Method.HEAD.isSame(request.getMethod())) {
+ redirectBuilder = ClassicRequestBuilder.get();
+ } else {
+ redirectBuilder = ClassicRequestBuilder.copy(currentScope.originalRequest);
+ }
+ break;
+ default:
+ redirectBuilder = ClassicRequestBuilder.copy(currentScope.originalRequest);
+ }
+ redirectBuilder.setUri(redirectUri);
+
+ HttpRoute currentRoute = currentScope.route;
+ if (!Objects.equals(currentRoute.getTargetHost(), newTarget)) {
+ final HttpRoute newRoute = this.routePlanner.determineRoute(newTarget, context);
+ if (!Objects.equals(currentRoute, newRoute)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("{} new route required", exchangeId);
+ }
+ final AuthExchange targetAuthExchange = context.getAuthExchange(currentRoute.getTargetHost());
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("{} resetting target auth state", exchangeId);
+ }
+ targetAuthExchange.reset();
+ if (currentRoute.getProxyHost() != null) {
+ final AuthExchange proxyAuthExchange = context.getAuthExchange(currentRoute.getProxyHost());
+ if (proxyAuthExchange.isConnectionBased()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("{} resetting proxy auth state", exchangeId);
+ }
+ proxyAuthExchange.reset();
+ }
+ }
+ currentRoute = newRoute;
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("{} redirecting to '{}' via {}", exchangeId, redirectUri, currentRoute);
+ }
+ currentScope = new ExecChain.Scope(
+ scope.exchangeId,
+ currentRoute,
+ redirectBuilder.build(),
+ scope.execRuntime,
+ scope.clientContext);
+ currentRequest = redirectBuilder.build();
+
+ EntityUtils.consume(response.getEntity());
+ response.close();
+ } else {
+ return response;
+ }
+ } catch (final RuntimeException | IOException ex) {
+ response.close();
+ throw ex;
+ } catch (final HttpException ex) {
+ // Protocol exception related to a direct.
+ // The underlying connection may still be salvaged.
+ try {
+ EntityUtils.consume(response.getEntity());
+ } catch (final IOException ioex) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("{} I/O error while releasing connection", exchangeId, ioex);
+ }
+ } finally {
+ response.close();
+ }
+ throw ex;
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/org/italiangrid/storm/webdav/spring/web/AppContextLoaderListener.java b/src/main/java/org/italiangrid/storm/webdav/spring/web/AppContextLoaderListener.java
index 1f39b68b..bcc4d36f 100644
--- a/src/main/java/org/italiangrid/storm/webdav/spring/web/AppContextLoaderListener.java
+++ b/src/main/java/org/italiangrid/storm/webdav/spring/web/AppContextLoaderListener.java
@@ -15,7 +15,7 @@
*/
package org.italiangrid.storm.webdav.spring.web;
-import javax.servlet.ServletContext;
+import jakarta.servlet.ServletContext;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.ContextLoaderListener;
diff --git a/src/main/java/org/italiangrid/storm/webdav/spring/web/HttpMethodRequestRejectedHandler.java b/src/main/java/org/italiangrid/storm/webdav/spring/web/HttpMethodRequestRejectedHandler.java
index 76f65842..62098bd2 100644
--- a/src/main/java/org/italiangrid/storm/webdav/spring/web/HttpMethodRequestRejectedHandler.java
+++ b/src/main/java/org/italiangrid/storm/webdav/spring/web/HttpMethodRequestRejectedHandler.java
@@ -18,9 +18,9 @@
import java.io.IOException;
import java.util.List;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
diff --git a/src/main/java/org/italiangrid/storm/webdav/spring/web/MvcConfig.java b/src/main/java/org/italiangrid/storm/webdav/spring/web/MvcConfig.java
index 57288094..672a1467 100644
--- a/src/main/java/org/italiangrid/storm/webdav/spring/web/MvcConfig.java
+++ b/src/main/java/org/italiangrid/storm/webdav/spring/web/MvcConfig.java
@@ -31,16 +31,16 @@
@Configuration
public class MvcConfig implements WebMvcConfigurer {
-
+
@Autowired
ServiceConfigurationProperties properties;
-
+
@Autowired
OAuthProperties oauthProperties;
@Autowired
StorageAreaConfiguration saConfig;
-
+
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new ViewUtilsInterceptor(properties, saConfig, oauthProperties));
diff --git a/src/main/java/org/italiangrid/storm/webdav/spring/web/ServletConfiguration.java b/src/main/java/org/italiangrid/storm/webdav/spring/web/ServletConfiguration.java
index 23ce8b49..fb01e534 100644
--- a/src/main/java/org/italiangrid/storm/webdav/spring/web/ServletConfiguration.java
+++ b/src/main/java/org/italiangrid/storm/webdav/spring/web/ServletConfiguration.java
@@ -41,7 +41,6 @@
import org.italiangrid.storm.webdav.server.servlet.SAIndexServlet;
import org.italiangrid.storm.webdav.server.servlet.SciTagFilter;
import org.italiangrid.storm.webdav.server.servlet.StoRMServlet;
-import org.italiangrid.storm.webdav.server.servlet.resource.StormResourceService;
import org.italiangrid.storm.webdav.server.tracing.LogbackAccessAuthnInfoFilter;
import org.italiangrid.storm.webdav.server.tracing.RequestIdFilter;
import org.italiangrid.storm.webdav.tpc.LocalURLService;
@@ -59,7 +58,7 @@
import org.thymeleaf.TemplateEngine;
import com.codahale.metrics.MetricRegistry;
-import com.codahale.metrics.servlets.MetricsServlet;
+import io.dropwizard.metrics.servlets.MetricsServlet;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -233,14 +232,12 @@ ServletRegistrationBean stormServlet(OAuthProperties oauthProperti
ServiceConfigurationProperties serviceConfig, StorageAreaConfiguration saConfig,
PathResolver pathResolver, TemplateEngine templateEngine) {
- ServletRegistrationBean stormServlet =
- new ServletRegistrationBean<>(new StoRMServlet(oauthProperties, serviceConfig, pathResolver,
- templateEngine, new StormResourceService()));
+ ServletRegistrationBean stormServlet = new ServletRegistrationBean<>(
+ new StoRMServlet(oauthProperties, serviceConfig, pathResolver, templateEngine));
stormServlet.addInitParameter("acceptRanges", "true");
stormServlet.addInitParameter("dirAllowed", "true");
- stormServlet.addInitParameter("aliases", "false");
- stormServlet.addInitParameter("gzip", "false");
+ stormServlet.addInitParameter("precompressed", "false");
saConfig.getStorageAreaInfo()
diff --git a/src/main/java/org/italiangrid/storm/webdav/tpc/TpcPlainConnectionSocketFactory.java b/src/main/java/org/italiangrid/storm/webdav/tpc/TpcPlainConnectionSocketFactory.java
index 04289a9d..2ba595b5 100644
--- a/src/main/java/org/italiangrid/storm/webdav/tpc/TpcPlainConnectionSocketFactory.java
+++ b/src/main/java/org/italiangrid/storm/webdav/tpc/TpcPlainConnectionSocketFactory.java
@@ -18,9 +18,10 @@
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
-import org.apache.http.HttpHost;
-import org.apache.http.conn.socket.PlainConnectionSocketFactory;
-import org.apache.http.protocol.HttpContext;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.util.TimeValue;
import org.italiangrid.storm.webdav.scitag.SciTag;
import org.italiangrid.storm.webdav.scitag.SciTagTransfer;
@@ -38,7 +39,7 @@ public TpcPlainConnectionSocketFactory() {
}
@Override
- public Socket connectSocket(int connectTimeout, Socket socket, HttpHost host,
+ public Socket connectSocket(TimeValue connectTimeout, Socket socket, HttpHost host,
InetSocketAddress remoteAddress, InetSocketAddress localAddress, HttpContext context)
throws IOException {
Socket s =
diff --git a/src/main/java/org/italiangrid/storm/webdav/tpc/TpcSSLConnectionSocketFactory.java b/src/main/java/org/italiangrid/storm/webdav/tpc/TpcSSLConnectionSocketFactory.java
index d7660cb6..d062fc51 100644
--- a/src/main/java/org/italiangrid/storm/webdav/tpc/TpcSSLConnectionSocketFactory.java
+++ b/src/main/java/org/italiangrid/storm/webdav/tpc/TpcSSLConnectionSocketFactory.java
@@ -18,8 +18,8 @@
import java.io.IOException;
import java.net.Socket;
import javax.net.ssl.SSLContext;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
-import org.apache.http.protocol.HttpContext;
+import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
+import org.apache.hc.core5.http.protocol.HttpContext;
import org.italiangrid.storm.webdav.scitag.SciTag;
import org.italiangrid.storm.webdav.scitag.SciTagTransfer;
diff --git a/src/main/java/org/italiangrid/storm/webdav/tpc/TpcUtils.java b/src/main/java/org/italiangrid/storm/webdav/tpc/TpcUtils.java
index 5e7a1ec0..ff5445dd 100644
--- a/src/main/java/org/italiangrid/storm/webdav/tpc/TpcUtils.java
+++ b/src/main/java/org/italiangrid/storm/webdav/tpc/TpcUtils.java
@@ -24,7 +24,7 @@
import java.util.function.Supplier;
import java.util.regex.Matcher;
-import javax.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletRequest;
import org.italiangrid.storm.webdav.config.StorageAreaInfo;
import org.italiangrid.storm.webdav.error.ResourceNotFound;
@@ -106,8 +106,9 @@ default boolean isCopy(HttpServletRequest request) {
}
default boolean isPushTpc(HttpServletRequest request, LocalURLService localUrlService) {
- return "COPY".equals(request.getMethod()) && (requestHasRemoteDestinationHeader(request, localUrlService)
- || requestHasTranferHeader(request));
+ return "COPY".equals(request.getMethod())
+ && (requestHasRemoteDestinationHeader(request, localUrlService)
+ || requestHasTranferHeader(request));
}
default boolean requestHasTranferHeader(HttpServletRequest request) {
diff --git a/src/main/java/org/italiangrid/storm/webdav/tpc/TransferFilter.java b/src/main/java/org/italiangrid/storm/webdav/tpc/TransferFilter.java
index c40d2a56..1f7882d3 100644
--- a/src/main/java/org/italiangrid/storm/webdav/tpc/TransferFilter.java
+++ b/src/main/java/org/italiangrid/storm/webdav/tpc/TransferFilter.java
@@ -15,7 +15,7 @@
*/
package org.italiangrid.storm.webdav.tpc;
-import static javax.servlet.http.HttpServletResponse.SC_ACCEPTED;
+import static jakarta.servlet.http.HttpServletResponse.SC_ACCEPTED;
import java.io.IOException;
import java.net.MalformedURLException;
@@ -23,17 +23,17 @@
import java.time.Clock;
import java.util.Optional;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.HttpResponseException;
+import org.apache.hc.client5.http.ClientProtocolException;
+import org.apache.hc.client5.http.HttpResponseException;
import org.italiangrid.storm.webdav.error.BadRequest;
import org.italiangrid.storm.webdav.error.ResourceNotFound;
import org.italiangrid.storm.webdav.scitag.SciTag;
@@ -183,11 +183,8 @@ protected void logTransferDone(GetTransferRequest req) {
if (TransferStatus.Status.DONE.equals(lastStatus.getStatus())) {
LOG.info(
"Pull third-party transfer completed: {}. Source: {}, Destination: {}, Bytes transferred: {}, Duration (msec): {}, Throughput: {}/sec, id: {}",
- lastStatus, req.remoteURI(), req.path(),
- req.bytesTransferred(),
- req.duration().toMillis(),
- getUserFriendlyThroughputString(req),
- req.uuid());
+ lastStatus, req.remoteURI(), req.path(), req.bytesTransferred(),
+ req.duration().toMillis(), getUserFriendlyThroughputString(req), req.uuid());
} else {
LOG.warn("Pull third-party transfer completed: {}. Source: {}, Destination: {}", lastStatus,
req.remoteURI(), req.path());
@@ -196,13 +193,12 @@ protected void logTransferDone(GetTransferRequest req) {
}
protected void logTransferDone(PutTransferRequest req) {
- if (req.lastTransferStatus().isPresent() && LOG.isInfoEnabled()) {
-
- LOG.info(
- "Push third-party transfer completed: {}. Source: {}, Destination: {}, Bytes transferred: {}, Duration (msec): {}, Throughput: {}/sec, id: {}",
- req.lastTransferStatus().get(), req.path(), req.remoteURI(),
- req.bytesTransferred(), req.duration().toMillis(), getUserFriendlyThroughputString(req),
- req.uuid());
+ if (LOG.isInfoEnabled()) {
+ req.lastTransferStatus()
+ .ifPresent(lastTransferStatus -> LOG.info(
+ "Push third-party transfer completed: {}. Source: {}, Destination: {}, Bytes transferred: {}, Duration (msec): {}, Throughput: {}/sec, id: {}",
+ lastTransferStatus, req.path(), req.remoteURI(), req.bytesTransferred(),
+ req.duration().toMillis(), getUserFriendlyThroughputString(req), req.uuid()));
}
}
diff --git a/src/main/java/org/italiangrid/storm/webdav/tpc/TransferFilterSupport.java b/src/main/java/org/italiangrid/storm/webdav/tpc/TransferFilterSupport.java
index ad0b487d..29e23bea 100644
--- a/src/main/java/org/italiangrid/storm/webdav/tpc/TransferFilterSupport.java
+++ b/src/main/java/org/italiangrid/storm/webdav/tpc/TransferFilterSupport.java
@@ -16,7 +16,7 @@
package org.italiangrid.storm.webdav.tpc;
import static java.lang.String.format;
-import static javax.servlet.http.HttpServletResponse.SC_PRECONDITION_FAILED;
+import static jakarta.servlet.http.HttpServletResponse.SC_PRECONDITION_FAILED;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import java.io.IOException;
@@ -28,11 +28,11 @@
import java.util.Enumeration;
import java.util.Optional;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.HttpResponseException;
+import org.apache.hc.client5.http.ClientProtocolException;
+import org.apache.hc.client5.http.HttpResponseException;
import org.italiangrid.storm.webdav.scitag.SciTag;
import org.italiangrid.storm.webdav.server.PathResolver;
import org.italiangrid.storm.webdav.tpc.transfer.TransferRequest;
@@ -99,9 +99,9 @@ protected Multimap getTransferHeaders(HttpServletRequest request
}
}
- if (isPushTpc(request, localURLService) && request.getContentLength() >= enableExpectContinueThreshold) {
- xferHeaders.put(org.apache.http.protocol.HTTP.EXPECT_DIRECTIVE,
- org.apache.http.protocol.HTTP.EXPECT_CONTINUE);
+ if (isPushTpc(request, localURLService)
+ && request.getContentLength() >= enableExpectContinueThreshold) {
+ xferHeaders.put("Expect", "100-continue");
}
return xferHeaders;
diff --git a/src/main/java/org/italiangrid/storm/webdav/tpc/http/GetResponseHandler.java b/src/main/java/org/italiangrid/storm/webdav/tpc/http/GetResponseHandler.java
index 98b16e66..24008134 100644
--- a/src/main/java/org/italiangrid/storm/webdav/tpc/http/GetResponseHandler.java
+++ b/src/main/java/org/italiangrid/storm/webdav/tpc/http/GetResponseHandler.java
@@ -21,10 +21,10 @@
import java.util.Collections;
import java.util.Map;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.StatusLine;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.italiangrid.storm.webdav.checksum.Adler32ChecksumOutputStream;
import org.italiangrid.storm.webdav.fs.attrs.ExtendedAttributesHelper;
import org.italiangrid.storm.webdav.tpc.transfer.GetTransferRequest;
@@ -33,7 +33,7 @@
import org.slf4j.LoggerFactory;
public class GetResponseHandler extends ResponseHandlerSupport
- implements org.apache.http.client.ResponseHandler {
+ implements HttpClientResponseHandler {
public static final int DEFAULT_BUFFER_SIZE = 4096;
@@ -83,15 +83,14 @@ private void writeEntityToStream(HttpEntity entity, OutputStream os)
@Override
- public Boolean handleResponse(HttpResponse response) throws IOException {
+ public Boolean handleResponse(ClassicHttpResponse response) throws IOException {
setupMDC();
LOG.debug("Response: {}", response);
- StatusLine sl = response.getStatusLine();
HttpEntity entity = response.getEntity();
- checkResponseStatus(sl);
+ checkResponseStatus(response);
Adler32ChecksumOutputStream checkedStream = null;
diff --git a/src/main/java/org/italiangrid/storm/webdav/tpc/http/HttpTransferClient.java b/src/main/java/org/italiangrid/storm/webdav/tpc/http/HttpTransferClient.java
index a4f77887..8a58225e 100644
--- a/src/main/java/org/italiangrid/storm/webdav/tpc/http/HttpTransferClient.java
+++ b/src/main/java/org/italiangrid/storm/webdav/tpc/http/HttpTransferClient.java
@@ -32,15 +32,14 @@
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
-import org.apache.http.HttpEntity;
-import org.apache.http.client.ClientProtocolException;
-import org.apache.http.client.HttpResponseException;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpHead;
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.client.protocol.HttpClientContext;
-import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.Method;
+import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
+import org.apache.hc.client5.http.ClientProtocolException;
+import org.apache.hc.client5.http.HttpResponseException;
+import org.apache.hc.client5.http.classic.methods.HttpHead;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.italiangrid.storm.webdav.config.ServiceConfigurationProperties;
import org.italiangrid.storm.webdav.config.ThirdPartyCopyProperties;
import org.italiangrid.storm.webdav.fs.attrs.ExtendedAttributesHelper;
@@ -105,10 +104,10 @@ public void destroy() throws Exception {
executorService.shutdownNow();
}
- HttpGet prepareRequest(GetTransferRequest request) {
+ BasicClassicHttpRequest prepareRequest(GetTransferRequest request) {
request.setTransferStatus(TransferStatus.builder(clock).inProgress(0));
- HttpGet get = new HttpGet(request.remoteURI());
+ BasicClassicHttpRequest get = new BasicClassicHttpRequest(Method.GET, request.remoteURI());
for (Map.Entry h : request.transferHeaders().entries()) {
get.addHeader(h.getKey(), h.getValue());
@@ -116,11 +115,11 @@ HttpGet prepareRequest(GetTransferRequest request) {
return get;
}
- HttpPut prepareRequest(PutTransferRequest request, HttpEntity cfe) {
+ BasicClassicHttpRequest prepareRequest(PutTransferRequest request, HttpEntity cfe) {
request.setTransferStatus(TransferStatus.builder(clock).inProgress(0));
- HttpPut put = new HttpPut(request.remoteURI());
+ BasicClassicHttpRequest put = new BasicClassicHttpRequest(Method.PUT, request.remoteURI());
for (Map.Entry h : request.transferHeaders().entries()) {
put.addHeader(h.getKey(), h.getValue());
@@ -167,7 +166,7 @@ StormCountingOutputStream prepareOutputStream(String path) {
public void handle(GetTransferRequest request, TransferStatusCallback cb) {
StormCountingOutputStream os = prepareOutputStream(resolver.resolvePath(request.path()));
- HttpGet get = prepareRequest(request);
+ BasicClassicHttpRequest get = prepareRequest(request);
HttpClientContext context = HttpClientContext.create();
ScheduledFuture> reportTask = executorService.scheduleAtFixedRate(
@@ -177,8 +176,8 @@ public void handle(GetTransferRequest request, TransferStatusCallback cb) {
try {
context.setAttribute(SciTag.SCITAG_ATTRIBUTE, request.scitag());
- httpClient.execute(get, new GetResponseHandler(request, os, attributesHelper,
- MDC.getCopyOfContextMap(), socketBufferSize, true), context);
+ httpClient.execute(get, context, new GetResponseHandler(request, os, attributesHelper,
+ MDC.getCopyOfContextMap(), socketBufferSize, true));
reportTask.cancel(true);
reportStatus(cb, request, statusBuilder.done(os.getCount()));
@@ -215,13 +214,15 @@ protected void checkOverwrite(PutTransferRequest request) throws IOException {
for (Map.Entry h : request.transferHeaders().entries()) {
head.addHeader(h.getKey(), h.getValue());
}
- CloseableHttpResponse response = httpClient.execute(head);
- if (response.getStatusLine().getStatusCode() == 200) {
- throw new TransferError("Remote file exists and overwrite is false");
- } else if (response.getStatusLine().getStatusCode() != 404) {
- throw new TransferError(format("Error checking if remote file exists: %d %s",
- response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase()));
- }
+ httpClient.execute(head, response -> {
+ if (response.getCode() == 200) {
+ throw new TransferError("Remote file exists and overwrite is false");
+ } else if (response.getCode() != 404) {
+ throw new TransferError(format("Error checking if remote file exists: %d %s",
+ response.getCode(), response.getReasonPhrase()));
+ }
+ return null;
+ });
}
}
@@ -230,7 +231,7 @@ public void handle(PutTransferRequest request, TransferStatusCallback cb) {
CountingFileEntity cfe = prepareFileEntity(resolver.resolvePath(request.path()));
- HttpPut put = null;
+ BasicClassicHttpRequest put = null;
HttpClientContext context = HttpClientContext.create();
put = prepareRequest(request, cfe);
@@ -242,7 +243,7 @@ public void handle(PutTransferRequest request, TransferStatusCallback cb) {
try {
checkOverwrite(request);
context.setAttribute(SciTag.SCITAG_ATTRIBUTE, request.scitag());
- httpClient.execute(put, new PutResponseHandler(MDC.getCopyOfContextMap()), context);
+ httpClient.execute(put, context, new PutResponseHandler(MDC.getCopyOfContextMap()));
reportTask.cancel(true);
reportStatus(cb, request, statusBuilder.done(cfe.getCount()));
} catch (HttpResponseException e) {
diff --git a/src/main/java/org/italiangrid/storm/webdav/tpc/http/HttpTransferClientMetricsWrapper.java b/src/main/java/org/italiangrid/storm/webdav/tpc/http/HttpTransferClientMetricsWrapper.java
index 80e58a3a..24c7c2c9 100644
--- a/src/main/java/org/italiangrid/storm/webdav/tpc/http/HttpTransferClientMetricsWrapper.java
+++ b/src/main/java/org/italiangrid/storm/webdav/tpc/http/HttpTransferClientMetricsWrapper.java
@@ -17,7 +17,7 @@
import static com.codahale.metrics.MetricRegistry.name;
-import org.apache.http.client.ClientProtocolException;
+import org.apache.hc.client5.http.ClientProtocolException;
import org.italiangrid.storm.webdav.tpc.transfer.GetTransferRequest;
import org.italiangrid.storm.webdav.tpc.transfer.PutTransferRequest;
import org.italiangrid.storm.webdav.tpc.transfer.TransferClient;
@@ -82,17 +82,18 @@ private void updateRequestOutcome(PutTransferRequest request) {
}
private void updateThroughput(GetTransferRequest request) {
-
- if (request.endedSuccesfully() && request.transferThroughputBytesPerSec().isPresent()) {
- pullThroughput.update(request.transferThroughputBytesPerSec().get().longValue());
+ if (request.endedSuccesfully()) {
+ request.transferThroughputBytesPerSec()
+ .ifPresent(transferThroughputBytesPerSec -> pullThroughput
+ .update(transferThroughputBytesPerSec.longValue()));
}
-
}
private void updateThroughput(PutTransferRequest request) {
-
- if (request.endedSuccesfully() && request.transferThroughputBytesPerSec().isPresent()) {
- pushThroughput.update(request.transferThroughputBytesPerSec().get().longValue());
+ if (request.endedSuccesfully()) {
+ request.transferThroughputBytesPerSec()
+ .ifPresent(transferThroughputBytesPerSec -> pushThroughput
+ .update(transferThroughputBytesPerSec.longValue()));
}
}
diff --git a/src/main/java/org/italiangrid/storm/webdav/tpc/http/PutResponseHandler.java b/src/main/java/org/italiangrid/storm/webdav/tpc/http/PutResponseHandler.java
index 7d4a5227..588fa39b 100644
--- a/src/main/java/org/italiangrid/storm/webdav/tpc/http/PutResponseHandler.java
+++ b/src/main/java/org/italiangrid/storm/webdav/tpc/http/PutResponseHandler.java
@@ -18,14 +18,15 @@
import java.io.IOException;
import java.util.Map;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.ResponseHandler;
-import org.apache.http.util.EntityUtils;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.io.HttpClientResponseHandler;
+import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
-public class PutResponseHandler extends ResponseHandlerSupport implements ResponseHandler {
+public class PutResponseHandler extends ResponseHandlerSupport
+ implements HttpClientResponseHandler {
public static final Logger LOG = LoggerFactory.getLogger(PutResponseHandler.class);
@@ -34,11 +35,11 @@ public PutResponseHandler(Map mdcContextMap) {
}
@Override
- public Boolean handleResponse(HttpResponse response) throws IOException {
+ public Boolean handleResponse(ClassicHttpResponse response) throws IOException {
setupMDC();
-
+
try {
- checkResponseStatus(response.getStatusLine());
+ checkResponseStatus(response);
return true;
} finally {
EntityUtils.consumeQuietly(response.getEntity());
diff --git a/src/main/java/org/italiangrid/storm/webdav/tpc/http/ResponseHandlerSupport.java b/src/main/java/org/italiangrid/storm/webdav/tpc/http/ResponseHandlerSupport.java
index 7ef4bb7d..25929a1c 100644
--- a/src/main/java/org/italiangrid/storm/webdav/tpc/http/ResponseHandlerSupport.java
+++ b/src/main/java/org/italiangrid/storm/webdav/tpc/http/ResponseHandlerSupport.java
@@ -17,8 +17,8 @@
import java.util.Map;
-import org.apache.http.StatusLine;
-import org.apache.http.client.HttpResponseException;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.client5.http.HttpResponseException;
import org.slf4j.MDC;
public abstract class ResponseHandlerSupport {
@@ -35,9 +35,9 @@ protected void setupMDC() {
}
}
- protected void checkResponseStatus(StatusLine sl) throws HttpResponseException {
- if (sl.getStatusCode() >= 300) {
- throw new HttpResponseException(sl.getStatusCode(), sl.getReasonPhrase());
+ protected void checkResponseStatus(HttpResponse response) throws HttpResponseException {
+ if (response.getCode() >= 300) {
+ throw new HttpResponseException(response.getCode(), response.getReasonPhrase());
}
}
diff --git a/src/main/java/org/italiangrid/storm/webdav/tpc/http/SuperLaxRedirectStrategy.java b/src/main/java/org/italiangrid/storm/webdav/tpc/http/SuperLaxRedirectStrategy.java
deleted file mode 100644
index 025f159f..00000000
--- a/src/main/java/org/italiangrid/storm/webdav/tpc/http/SuperLaxRedirectStrategy.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * Copyright (c) Istituto Nazionale di Fisica Nucleare, 2014-2023.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.italiangrid.storm.webdav.tpc.http;
-
-import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.ProtocolException;
-import org.apache.http.client.methods.HttpDelete;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpHead;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.impl.client.DefaultRedirectStrategy;
-import org.apache.http.protocol.HttpContext;
-
-public class SuperLaxRedirectStrategy extends DefaultRedirectStrategy {
-
- /*
- * SUH stands for Sad, Useless Header.
- */
- public static final String SUH_HEADER = "X-SUH";
-
- public static final String AUTHORIZATION_HEADER = "Authorization";
-
- private static final String[] REDIRECT_METHODS = new String[] {HttpGet.METHOD_NAME,
- HttpPut.METHOD_NAME, HttpPost.METHOD_NAME, HttpHead.METHOD_NAME, HttpDelete.METHOD_NAME};
-
- public static final SuperLaxRedirectStrategy INSTANCE = new SuperLaxRedirectStrategy();
-
- private SuperLaxRedirectStrategy() {
- // empty ctor
- }
-
- @Override
- public HttpUriRequest getRedirect(HttpRequest request, HttpResponse response, HttpContext context)
- throws ProtocolException {
-
- HttpUriRequest redirect = super.getRedirect(request, response, context);
-
- /*
- * If this method returns an HttpUriRequest that has no HTTP headers then the RedirectExec code
- * will copy all the headers from the original request into the HttpUriRequest.
- * DefaultRedirectStrategy returns such requests under several circumstances. Therefore, in
- * order to suppress the Authorization header we must ensure the returned request
- * includes headers.
- */
- if (!redirect.headerIterator().hasNext()) {
- redirect.setHeaders(request.getAllHeaders());
- }
-
- redirect.removeHeaders(AUTHORIZATION_HEADER);
-
- if (!redirect.headerIterator().hasNext()) {
- /*
- * If the Authorization header was the only one set in the original request or in the redirect, we need to
- * add back an empty header otherwise the RedirectExec code will copy the Authorization header from the original
- * request back in.
- */
- redirect.addHeader(SUH_HEADER, "");
- }
-
- return redirect;
- }
-
-
- @Override
- protected boolean isRedirectable(String method) {
- for (final String m : REDIRECT_METHODS) {
- if (m.equalsIgnoreCase(method)) {
- return true;
- }
- }
-
- return false;
- }
-}
diff --git a/src/main/java/org/italiangrid/storm/webdav/tpc/transfer/TransferClient.java b/src/main/java/org/italiangrid/storm/webdav/tpc/transfer/TransferClient.java
index 58dfd993..057758b9 100644
--- a/src/main/java/org/italiangrid/storm/webdav/tpc/transfer/TransferClient.java
+++ b/src/main/java/org/italiangrid/storm/webdav/tpc/transfer/TransferClient.java
@@ -15,12 +15,14 @@
*/
package org.italiangrid.storm.webdav.tpc.transfer;
-import org.apache.http.client.ClientProtocolException;
+import org.apache.hc.client5.http.ClientProtocolException;
public interface TransferClient {
- void handle(GetTransferRequest request, TransferStatusCallback status) throws ClientProtocolException;
-
- void handle(PutTransferRequest request, TransferStatusCallback status) throws ClientProtocolException;
+ void handle(GetTransferRequest request, TransferStatusCallback status)
+ throws ClientProtocolException;
+
+ void handle(PutTransferRequest request, TransferStatusCallback status)
+ throws ClientProtocolException;
}
diff --git a/src/main/java/org/italiangrid/storm/webdav/tpc/utils/Adler32DigestHeaderHelper.java b/src/main/java/org/italiangrid/storm/webdav/tpc/utils/Adler32DigestHeaderHelper.java
index c75c991f..1f0469f4 100644
--- a/src/main/java/org/italiangrid/storm/webdav/tpc/utils/Adler32DigestHeaderHelper.java
+++ b/src/main/java/org/italiangrid/storm/webdav/tpc/utils/Adler32DigestHeaderHelper.java
@@ -22,8 +22,8 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import org.apache.http.Header;
-import org.apache.http.HttpResponse;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpResponse;
public class Adler32DigestHeaderHelper {
diff --git a/src/main/java/org/italiangrid/storm/webdav/tpc/utils/CountingFileEntity.java b/src/main/java/org/italiangrid/storm/webdav/tpc/utils/CountingFileEntity.java
index e0d5e365..8c7757d5 100644
--- a/src/main/java/org/italiangrid/storm/webdav/tpc/utils/CountingFileEntity.java
+++ b/src/main/java/org/italiangrid/storm/webdav/tpc/utils/CountingFileEntity.java
@@ -15,13 +15,13 @@
*/
package org.italiangrid.storm.webdav.tpc.utils;
-import static org.apache.http.entity.ContentType.APPLICATION_OCTET_STREAM;
+import static org.apache.hc.core5.http.ContentType.APPLICATION_OCTET_STREAM;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
-import org.apache.http.entity.FileEntity;
+import org.apache.hc.core5.http.io.entity.FileEntity;
import com.google.common.io.CountingOutputStream;
diff --git a/src/main/java/org/italiangrid/storm/webdav/web/ViewUtilsInterceptor.java b/src/main/java/org/italiangrid/storm/webdav/web/ViewUtilsInterceptor.java
index f1b54e2b..4021e2df 100644
--- a/src/main/java/org/italiangrid/storm/webdav/web/ViewUtilsInterceptor.java
+++ b/src/main/java/org/italiangrid/storm/webdav/web/ViewUtilsInterceptor.java
@@ -15,8 +15,8 @@
*/
package org.italiangrid.storm.webdav.web;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
import org.italiangrid.storm.webdav.authn.AuthenticationUtils;
import org.italiangrid.storm.webdav.config.OAuthProperties;
diff --git a/src/main/resources/application-redis.yml b/src/main/resources/application-redis.yml
index a1431435..5e77524b 100644
--- a/src/main/resources/application-redis.yml
+++ b/src/main/resources/application-redis.yml
@@ -4,10 +4,11 @@ management:
enabled: true
spring:
- redis:
- host: ${STORM_WEBDAV_REDIS_HOST:localhost}
- port: ${STORM_WEBDAV_REDIS_PORT:6379}
- password: ${STORM_WEBDAV_REDIS_PASSWORD:}
+ data:
+ redis:
+ host: ${STORM_WEBDAV_REDIS_HOST:localhost}
+ port: ${STORM_WEBDAV_REDIS_PORT:6379}
+ password: ${STORM_WEBDAV_REDIS_PASSWORD:}
session:
- store-type: redis
\ No newline at end of file
+ store-type: redis
diff --git a/src/test/java/org/italiangrid/storm/webdav/server/TLSConnectorBuilderTest.java b/src/test/java/org/italiangrid/storm/webdav/server/TLSConnectorBuilderTest.java
index b7fcbba9..408bee0f 100644
--- a/src/test/java/org/italiangrid/storm/webdav/server/TLSConnectorBuilderTest.java
+++ b/src/test/java/org/italiangrid/storm/webdav/server/TLSConnectorBuilderTest.java
@@ -24,7 +24,7 @@
import javax.net.ssl.KeyManager;
-import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
@@ -114,4 +114,4 @@ void tlsConnectorBuilderTests() {
ServerConnector c = builder.build();
assertThat(c.getPort(), is(1234));
}
-}
\ No newline at end of file
+}
diff --git a/src/test/java/org/italiangrid/storm/webdav/server/servlet/AvoidTraceMethodFilterTest.java b/src/test/java/org/italiangrid/storm/webdav/server/servlet/AvoidTraceMethodFilterTest.java
index f4ed7af1..fb11740b 100644
--- a/src/test/java/org/italiangrid/storm/webdav/server/servlet/AvoidTraceMethodFilterTest.java
+++ b/src/test/java/org/italiangrid/storm/webdav/server/servlet/AvoidTraceMethodFilterTest.java
@@ -70,27 +70,27 @@ void traceAsNonAnonymousOnRootLeadsTo405() throws Exception {
@Test
void trackAsAnonymousLeadsTo405() throws Exception {
- mvc.perform(MockMvcRequestBuilders.request("TRACK", new URI("/test/file")))
+ mvc.perform(MockMvcRequestBuilders.request(HttpMethod.valueOf("TRACK"), new URI("/test/file")))
.andExpect(status().isMethodNotAllowed());
}
@Test
@WithMockVOMSUser(vos = "wlcg", saReadPermissions = {"wlcg"})
void trackAsNonAnonymousLeadsTo405() throws Exception {
- mvc.perform(MockMvcRequestBuilders.request("TRACK", new URI("/wlcg/file")))
+ mvc.perform(MockMvcRequestBuilders.request(HttpMethod.valueOf("TRACK"), new URI("/wlcg/file")))
.andExpect(status().isMethodNotAllowed());
}
@Test
void trackAsAnonymousOnRootLeadsTo405() throws Exception {
- mvc.perform(MockMvcRequestBuilders.request("TRACK", new URI("/")))
+ mvc.perform(MockMvcRequestBuilders.request(HttpMethod.valueOf("TRACK"), new URI("/")))
.andExpect(status().isMethodNotAllowed());
}
@Test
@WithMockVOMSUser(vos = "wlcg", saReadPermissions = {"wlcg"})
void trackAsNonAnonymousOnRootLeadsTo405() throws Exception {
- mvc.perform(MockMvcRequestBuilders.request("TRACK", new URI("/")))
+ mvc.perform(MockMvcRequestBuilders.request(HttpMethod.valueOf("TRACK"), new URI("/")))
.andExpect(status().isMethodNotAllowed());
}
diff --git a/src/test/java/org/italiangrid/storm/webdav/test/authz/AuthzTest.java b/src/test/java/org/italiangrid/storm/webdav/test/authz/AuthzTest.java
index 698d9572..4d0e697f 100644
--- a/src/test/java/org/italiangrid/storm/webdav/test/authz/AuthzTest.java
+++ b/src/test/java/org/italiangrid/storm/webdav/test/authz/AuthzTest.java
@@ -19,6 +19,7 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.italiangrid.storm.webdav.authz.VOMSAuthenticationFilter;
+import org.italiangrid.storm.webdav.config.ServiceConfigurationProperties;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
@@ -43,6 +44,9 @@ class AuthzTest {
@Autowired
VOMSAuthenticationFilter filter;
+ @Autowired
+ ServiceConfigurationProperties props;
+
@BeforeEach
public void setup() {
filter.setCheckForPrincipalChanges(false);
diff --git a/src/test/java/org/italiangrid/storm/webdav/test/authz/integration/AuthorizationIntegrationTests.java b/src/test/java/org/italiangrid/storm/webdav/test/authz/integration/AuthorizationIntegrationTests.java
index eddc1680..8b2cf84c 100644
--- a/src/test/java/org/italiangrid/storm/webdav/test/authz/integration/AuthorizationIntegrationTests.java
+++ b/src/test/java/org/italiangrid/storm/webdav/test/authz/integration/AuthorizationIntegrationTests.java
@@ -36,6 +36,7 @@
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.http.HttpMethod;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.test.context.support.WithAnonymousUser;
import org.springframework.test.context.ActiveProfiles;
@@ -300,17 +301,17 @@ void readWriteAccessAsJwtWithAllowedGroup() throws Exception {
@WithMockVOMSUser(vos = "wlcg", saReadPermissions = {"wlcg"})
@Test
void localVomsCopyRequiresWithReadPermissionsGetsAccessDenied() throws Exception {
- mvc.perform(request("COPY", URI.create("http://localhost/wlcg/source")).header("Destination",
- "http://localhost/wlcg/destination"))
+ mvc
+ .perform(request(HttpMethod.valueOf("COPY"), URI.create("http://localhost/wlcg/source"))
+ .header("Destination", "http://localhost/wlcg/destination"))
.andExpect(status().isForbidden());
}
@WithMockVOMSUser(vos = "wlcg", saWritePermissions = {"wlcg"}, saReadPermissions = {"wlcg"})
@Test
void localVomsCopyRequiresReadAndWritePermissions() throws Exception {
- mvc.perform(request("COPY", URI.create("http://localhost/wlcg/source")).header("Destination",
- "http://localhost/wlcg/destination"))
- .andExpect(status().isOk());
+ mvc.perform(request(HttpMethod.valueOf("COPY"), URI.create("http://localhost/wlcg/source"))
+ .header("Destination", "http://localhost/wlcg/destination")).andExpect(status().isOk());
}
@Test
@@ -322,7 +323,7 @@ void tpcJwtPullCopyBlockedWithStorageReadScope() throws Exception {
.claim("scope", "storage.read:/")
.build();
- mvc.perform(request("COPY", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("COPY"), URI.create("http://localhost/wlcg/source"))
.header("Source", "http://localhost/wlcg/destination")
.with(jwt().jwt(token))).andExpect(status().isForbidden());
}
@@ -336,7 +337,7 @@ void tpcJwtPullCopyRequiresStorageModifyScope() throws Exception {
.claim("scope", "storage.modify:/")
.build();
- mvc.perform(request("COPY", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("COPY"), URI.create("http://localhost/wlcg/source"))
.header("Source", "http://localhost/wlcg/destination")
.with(jwt().jwt(token))).andExpect(status().isAccepted());
}
@@ -350,7 +351,7 @@ void tpcJwtPullCopyRequiresStorageModifyScopeWithRightPath() throws Exception {
.claim("scope", "storage.modify:/subdir storage.read:/")
.build();
- mvc.perform(request("COPY", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("COPY"), URI.create("http://localhost/wlcg/source"))
.header("Source", "http://localhost/wlcg/destination")
.with(jwt().jwt(token))).andExpect(status().isForbidden());
}
@@ -365,7 +366,7 @@ void tpcJwtLocalCopyRequiresAppropriatePermissions() throws Exception {
.claim("scope", "storage.read:/")
.build();
- mvc.perform(request("COPY", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("COPY"), URI.create("http://localhost/wlcg/source"))
.header("Destination", "http://localhost/wlcg/destination")
.with(jwt().jwt(token))).andExpect(status().isForbidden());
@@ -376,7 +377,7 @@ void tpcJwtLocalCopyRequiresAppropriatePermissions() throws Exception {
.claim("scope", "storage.modify:/")
.build();
- mvc.perform(request("COPY", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("COPY"), URI.create("http://localhost/wlcg/source"))
.header("Destination", "http://localhost/wlcg/destination")
.with(jwt().jwt(token))).andExpect(status().isForbidden());
@@ -387,7 +388,7 @@ void tpcJwtLocalCopyRequiresAppropriatePermissions() throws Exception {
.claim("scope", "storage.read:/ storage.modify:/")
.build();
- mvc.perform(request("COPY", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("COPY"), URI.create("http://localhost/wlcg/source"))
.header("Destination", "http://localhost/wlcg/destination")
.with(jwt().jwt(token))).andExpect(status().isOk());
@@ -398,7 +399,7 @@ void tpcJwtLocalCopyRequiresAppropriatePermissions() throws Exception {
.claim("scope", "storage.read:/subdir storage.modify:/")
.build();
- mvc.perform(request("COPY", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("COPY"), URI.create("http://localhost/wlcg/source"))
.header("Destination", "http://localhost/wlcg/destination")
.with(jwt().jwt(token))).andExpect(status().isForbidden());
@@ -409,7 +410,7 @@ void tpcJwtLocalCopyRequiresAppropriatePermissions() throws Exception {
.claim("scope", "storage.read:/ storage.modify:/subdir")
.build();
- mvc.perform(request("COPY", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("COPY"), URI.create("http://localhost/wlcg/source"))
.header("Destination", "http://localhost/wlcg/destination")
.with(jwt().jwt(token))).andExpect(status().isForbidden());
@@ -420,7 +421,7 @@ void tpcJwtLocalCopyRequiresAppropriatePermissions() throws Exception {
.claim("scope", "storage.read:/source storage.modify:/destination")
.build();
- mvc.perform(request("COPY", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("COPY"), URI.create("http://localhost/wlcg/source"))
.header("Destination", "http://localhost/wlcg/destination")
.with(jwt().jwt(token))).andExpect(status().isOk());
}
@@ -434,7 +435,7 @@ void tpcJwtLocalMoveRequiresAppropriatePermissions() throws Exception {
.claim("scope", "storage.read:/")
.build();
- mvc.perform(request("MOVE", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("MOVE"), URI.create("http://localhost/wlcg/source"))
.header("Destination", "http://localhost/wlcg/destination")
.with(jwt().jwt(token))).andExpect(status().isForbidden());
@@ -445,7 +446,7 @@ void tpcJwtLocalMoveRequiresAppropriatePermissions() throws Exception {
.claim("scope", "storage.modify:/")
.build();
- mvc.perform(request("MOVE", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("MOVE"), URI.create("http://localhost/wlcg/source"))
.header("Destination", "http://localhost/wlcg/destination")
.with(jwt().jwt(token))).andExpect(status().isOk());
@@ -457,7 +458,7 @@ void tpcJwtLocalMoveRequiresAppropriatePermissions() throws Exception {
.claim("scope", "storage.modify:/subdir")
.build();
- mvc.perform(request("MOVE", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("MOVE"), URI.create("http://localhost/wlcg/source"))
.header("Destination", "http://localhost/wlcg/destination")
.with(jwt().jwt(token))).andExpect(status().isForbidden());
@@ -469,7 +470,7 @@ void tpcJwtLocalMoveRequiresAppropriatePermissions() throws Exception {
.claim("scope", "openid storage.modify:/source storage.modify:/destination")
.build();
- mvc.perform(request("MOVE", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("MOVE"), URI.create("http://localhost/wlcg/source"))
.header("Destination", "http://localhost/wlcg/destination")
.with(jwt().jwt(token))).andExpect(status().isOk());
}
@@ -484,7 +485,7 @@ void tpcJwtFineGrainedAuthzCopyTests() throws Exception {
.subject("123")
.build();
- mvc.perform(request("COPY", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("COPY"), URI.create("http://localhost/wlcg/source"))
.header("Destination", "http://localhost/wlcg/destination")
.with(jwt().jwt(token).authorities(authConverter))).andExpect(status().isForbidden());
@@ -496,7 +497,7 @@ void tpcJwtFineGrainedAuthzCopyTests() throws Exception {
.claim("groups", "/example/admins")
.build();
- mvc.perform(request("COPY", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("COPY"), URI.create("http://localhost/wlcg/source"))
.header("Destination", "http://localhost/wlcg/destination")
.with(jwt().jwt(token).authorities(authConverter))).andExpect(status().isOk());
@@ -507,7 +508,7 @@ void tpcJwtFineGrainedAuthzCopyTests() throws Exception {
.claim("groups", "/example")
.build();
- mvc.perform(request("COPY", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("COPY"), URI.create("http://localhost/wlcg/source"))
.header("Destination", "http://localhost/wlcg/destination")
.with(jwt().jwt(token).authorities(authConverter))).andExpect(status().isForbidden());
@@ -518,7 +519,7 @@ void tpcJwtFineGrainedAuthzCopyTests() throws Exception {
.claim("groups", "/example/admins")
.build();
- mvc.perform(request("COPY", URI.create("http://localhost/wlcg/source"))
+ mvc.perform(request(HttpMethod.valueOf("COPY"), URI.create("http://localhost/wlcg/source"))
.header("Destination", "http://localhost/wlcg/destination")
.with(jwt().jwt(token).authorities(authConverter))).andExpect(status().isForbidden());
diff --git a/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/AuthzPdpTests.java b/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/AuthzPdpTests.java
index 342326fc..460a0fbb 100644
--- a/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/AuthzPdpTests.java
+++ b/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/AuthzPdpTests.java
@@ -27,7 +27,7 @@
import java.util.List;
-import javax.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletRequest;
import org.italiangrid.storm.webdav.authz.VOMSFQANAuthority;
import org.italiangrid.storm.webdav.authz.VOMSVOAuthority;
diff --git a/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/LocalAuthzPdpTests.java b/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/LocalAuthzPdpTests.java
index 3f082100..26be701f 100644
--- a/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/LocalAuthzPdpTests.java
+++ b/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/LocalAuthzPdpTests.java
@@ -28,7 +28,7 @@
import java.net.URL;
import java.util.Enumeration;
-import javax.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletRequest;
import org.italiangrid.storm.webdav.authz.pdp.LocalAuthorizationPdp;
import org.italiangrid.storm.webdav.authz.pdp.PathAuthorizationResult;
diff --git a/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/PolicyPropertiesValidationTests.java b/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/PolicyPropertiesValidationTests.java
index 31cfea4f..913b5a54 100644
--- a/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/PolicyPropertiesValidationTests.java
+++ b/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/PolicyPropertiesValidationTests.java
@@ -25,10 +25,10 @@
import java.util.Locale;
import java.util.Set;
-import javax.validation.ConstraintViolation;
-import javax.validation.Validation;
-import javax.validation.Validator;
-import javax.validation.ValidatorFactory;
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.Validation;
+import jakarta.validation.Validator;
+import jakarta.validation.ValidatorFactory;
import org.italiangrid.storm.webdav.authz.pdp.PolicyEffect;
import org.italiangrid.storm.webdav.config.FineGrainedAuthzPolicyProperties;
diff --git a/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/ScopePathAuthzPdpTests.java b/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/ScopePathAuthzPdpTests.java
index 803f7f59..726568f9 100644
--- a/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/ScopePathAuthzPdpTests.java
+++ b/src/test/java/org/italiangrid/storm/webdav/test/authz/pdp/ScopePathAuthzPdpTests.java
@@ -30,7 +30,7 @@
import java.net.URL;
import java.util.Enumeration;
-import javax.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletRequest;
import org.italiangrid.storm.webdav.authz.pdp.PathAuthorizationResult;
import org.italiangrid.storm.webdav.authz.pdp.PathAuthorizationResult.Decision;
@@ -460,8 +460,7 @@ void parentDirCreationIsNotAllowedWithWrongScopes() {
lenient().when(pathResolver.resolveStorageArea(anyString())).thenReturn(sa);
lenient().when(request.getPathInfo()).thenReturn("test/dir/subdir");
- lenient().when(jwt.getClaimAsString(SCOPE_CLAIM))
- .thenReturn("openid storage.read:/dir/subdir");
+ lenient().when(jwt.getClaimAsString(SCOPE_CLAIM)).thenReturn("openid storage.read:/dir/subdir");
lenient().when(request.getMethod()).thenReturn("MKCOL");
PathAuthorizationResult result =
pdp.authorizeRequest(newAuthorizationRequest(request, jwtAuth));
diff --git a/src/test/java/org/italiangrid/storm/webdav/test/oauth/integration/OAuthAuthzServerIntegrationTests.java b/src/test/java/org/italiangrid/storm/webdav/test/oauth/integration/OAuthAuthzServerIntegrationTests.java
index 41eaaac3..f2d36cf8 100644
--- a/src/test/java/org/italiangrid/storm/webdav/test/oauth/integration/OAuthAuthzServerIntegrationTests.java
+++ b/src/test/java/org/italiangrid/storm/webdav/test/oauth/integration/OAuthAuthzServerIntegrationTests.java
@@ -16,7 +16,6 @@
package org.italiangrid.storm.webdav.test.oauth.integration;
import static java.lang.String.format;
-import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
import static org.hamcrest.CoreMatchers.is;
import static org.italiangrid.storm.webdav.oauth.authzserver.ErrorResponseDTO.UNSUPPORTED_GRANT_TYPE;
import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED;
@@ -30,6 +29,7 @@
import java.time.Instant;
import java.time.ZoneId;
+import org.apache.commons.lang3.RandomStringUtils;
import org.italiangrid.storm.webdav.authz.VOMSAuthenticationFilter;
import org.italiangrid.storm.webdav.config.ServiceConfigurationProperties;
import org.italiangrid.storm.webdav.oauth.authzserver.AccessTokenRequest;
@@ -161,7 +161,9 @@ void requestedLifetimeLimited() throws Exception {
@WithMockVOMSUser
void scopeLengthIsChecked() throws Exception {
- String randomAlphabetic = randomAlphabetic(AccessTokenRequest.MAX_SCOPE_LENGTH);
+ RandomStringUtils randomStringUtils = RandomStringUtils.insecure();
+
+ String randomAlphabetic = randomStringUtils.nextAlphabetic(AccessTokenRequest.MAX_SCOPE_LENGTH);
mvc
.perform(post("/oauth/token").content(format("%s&scope=%s", CONTENT, randomAlphabetic))
@@ -169,7 +171,7 @@ void scopeLengthIsChecked() throws Exception {
.andExpect(status().isOk())
.andExpect(jsonPath("$.access_token").exists());
- randomAlphabetic = randomAlphabetic(AccessTokenRequest.MAX_SCOPE_LENGTH + 1);
+ randomAlphabetic = randomStringUtils.nextAlphabetic(AccessTokenRequest.MAX_SCOPE_LENGTH + 1);
mvc
.perform(post("/oauth/token").content(format("%s&scope=%s", CONTENT, randomAlphabetic))
diff --git a/src/test/java/org/italiangrid/storm/webdav/test/oauth/jwk/OidcConfigurationFetcherTest.java b/src/test/java/org/italiangrid/storm/webdav/test/oauth/jwk/OidcConfigurationFetcherTest.java
index 0725f914..64f93704 100644
--- a/src/test/java/org/italiangrid/storm/webdav/test/oauth/jwk/OidcConfigurationFetcherTest.java
+++ b/src/test/java/org/italiangrid/storm/webdav/test/oauth/jwk/OidcConfigurationFetcherTest.java
@@ -49,6 +49,7 @@
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpStatus;
+import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
@@ -94,8 +95,7 @@ private ResponseEntity