Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,6 @@
<version>2.1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-fileupload2-jakarta-servlet5</artifactId>
<version>2.0.0-M2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.framework</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

import org.apache.commons.fileupload2.core.DiskFileItem;
import jakarta.servlet.http.Part;

/**
* The <code>MultipartRequestParameter</code> represents a request parameter
Expand All @@ -34,23 +35,35 @@
*/
public class MultipartRequestParameter extends AbstractRequestParameter {

private final DiskFileItem delegatee;
private final Part part;

private String encodedFileName;

private String cachedValue;

public MultipartRequestParameter(DiskFileItem delegatee) {
super(delegatee.getFieldName(), null);
this.delegatee = delegatee;
private byte[] cachedContent;

public static final String FORM_DATA = "form-data";

public static final String ATTACHMENT = "attachment";

private static final String FILENAME_KEY = "filename";

public MultipartRequestParameter(Part part) {
this(part, null);
}

public MultipartRequestParameter(Part part, String encoding) {
super(part.getName(), encoding);
this.part = part;
}

void dispose() throws IOException {
this.delegatee.delete();
this.part.delete();
}

DiskFileItem getFileItem() {
return this.delegatee;
Part getPart() {
return this.part;
}

@Override
Expand All @@ -60,36 +73,32 @@ void setEncoding(String encoding) {
}

public byte[] get() {
return this.delegatee.get();
if (cachedContent != null) {
return cachedContent;
}
// read the content of the part into a byte array
try (InputStream in = part.getInputStream()) {
cachedContent = in.readAllBytes();
return cachedContent;
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
}

public String getContentType() {
return this.delegatee.getContentType();
return this.part.getContentType();
}

public InputStream getInputStream() throws IOException {
return this.delegatee.getInputStream();
return this.part.getInputStream();
}

public String getFileName() {
if (this.encodedFileName == null && this.delegatee.getName() != null) {
String tmpFileName = this.delegatee.getName();
if (this.getEncoding() != null) {
try {
byte[] rawName = tmpFileName.getBytes(Util.ENCODING_DIRECT);
tmpFileName = new String(rawName, this.getEncoding());
} catch (UnsupportedEncodingException uee) {
// might log, but actually don't care
}
}
this.encodedFileName = tmpFileName;
}

return this.encodedFileName;
return this.part.getSubmittedFileName();
}

public long getSize() {
return this.delegatee.getSize();
return this.part.getSize();
}

public String getString() {
Expand Down Expand Up @@ -117,15 +126,15 @@ public String getString() {
return this.cachedValue;
}

return this.delegatee.getString();
return new String(this.get(), getCharset());
}

public String getString(String enc) throws UnsupportedEncodingException {
return new String(this.get(), enc);
}

public boolean isFormField() {
return this.delegatee.isFormField();
return getFileName() == null;
}

public String toString() {
Expand All @@ -135,4 +144,16 @@ public String toString() {

return "File: " + this.getFileName() + " (" + this.getSize() + " bytes)";
}

private Charset getCharset() {
final String contentType = getContentType();
if (contentType != null) {
for (String param : contentType.split(";")) {
if (param.trim().toLowerCase().startsWith("charset=")) {
return Charset.forName(param.trim().substring("charset=".length()));
}
}
}
return Charset.forName(Util.ENCODING_DIRECT);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,12 @@
import java.util.Locale;
import java.util.Map;

import jakarta.servlet.MultipartConfigElement;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload2.core.DiskFileItem;
import org.apache.commons.fileupload2.core.DiskFileItemFactory;
import org.apache.commons.fileupload2.core.FileUploadException;
import org.apache.commons.fileupload2.core.RequestContext;
import org.apache.commons.fileupload2.jakarta.servlet5.JakartaServletDiskFileUpload;
import org.apache.commons.fileupload2.jakarta.servlet5.JakartaServletFileUpload;
import org.apache.commons.fileupload2.jakarta.servlet5.JakartaServletRequestContext;
import jakarta.servlet.http.Part;
import org.apache.sling.api.request.RequestParameter;
import org.apache.sling.api.request.RequestParameterMap;
import org.apache.sling.api.resource.ResourceResolver;
Expand Down Expand Up @@ -303,8 +299,7 @@ private ParameterMap getRequestParameterMapInternal() {
}

// Multipart POST
if (JakartaServletFileUpload.isMultipartContent(
new JakartaServletRequestContext(this.getServletRequest()))) {
if (isMultipartContent(this.getServletRequest())) {
if (isStreamed(parameters, this.getServletRequest())) {
// special case, the request is Multipart and streamed processing has been requested
try {
Expand All @@ -314,7 +309,7 @@ private ParameterMap getRequestParameterMapInternal() {
new RequestPartsIterator(this.getServletRequest()));
this.log.debug(
"getRequestParameterMapInternal: Iterator<javax.servlet.http.Part> available as request attribute named request-parts-iterator");
} catch (IOException e) {
} catch (IOException | ServletException e) {
this.log.error(
"getRequestParameterMapInternal: Error parsing multipart streamed request", e);
}
Expand Down Expand Up @@ -393,39 +388,45 @@ private static final boolean isWWWFormEncodedContent(HttpServletRequest request)
return false;
}

private boolean isMultipartContent(final HttpServletRequest request) {
String contentType = request.getContentType();
if (contentType == null) {
return false;
}
return contentType.toLowerCase(Locale.ENGLISH).startsWith("multipart/form-data");
}

private void parseMultiPartPost(ParameterMap parameters) {

// Create a new file upload handler
JakartaServletDiskFileUpload upload = new JakartaServletDiskFileUpload();
upload.setSizeMax(ParameterSupport.maxRequestSize);
upload.setFileSizeMax(ParameterSupport.maxFileSize);
upload.setFileItemFactory(DiskFileItemFactory.builder()
.setBufferSize(ParameterSupport.fileSizeThreshold)
.setPath(ParameterSupport.location.toPath())
.get());
upload.setFileCountMax(ParameterSupport.maxFileCount);
RequestContext rc = new JakartaServletRequestContext(this.getServletRequest()) {
@Override
public String getCharacterEncoding() {
String enc = super.getCharacterEncoding();
return (enc != null) ? enc : Util.ENCODING_DIRECT;
}
};
HttpServletRequest request = this.getServletRequest();
String encoding = request.getCharacterEncoding();
if (encoding == null) {
encoding = Util.ENCODING_DIRECT;
}

MultipartConfigElement multipartConfig = new MultipartConfigElement(
ParameterSupport.location.toPath().toString(),
ParameterSupport.maxFileSize,
ParameterSupport.maxRequestSize,
ParameterSupport.fileSizeThreshold);
request.setAttribute("org.eclipse.jetty.multipartConfig", multipartConfig);

// Parse the request
List<?> /* FileItem */ items = null;
try {
items = upload.parseRequest(rc);
} catch (FileUploadException fue) {
this.log.error("parseMultiPartPost: Error parsing request", fue);
}
Collection<Part> parts = request.getParts();
long fileCount =
parts.stream().filter(p -> p.getSubmittedFileName() != null).count();

if (items != null && items.size() > 0) {
for (Iterator<?> ii = items.iterator(); ii.hasNext(); ) {
DiskFileItem fileItem = (DiskFileItem) ii.next();
RequestParameter pp = new MultipartRequestParameter(fileItem);
parameters.addParameter(pp, false);
if (fileCount > ParameterSupport.maxFileCount) {
throw new ServletException("Too many files uploaded. Limit is " + ParameterSupport.maxFileCount);
}

for (Part part : parts) {
parameters.addParameter(new MultipartRequestParameter(part, encoding), false);
}

} catch (Exception e) {
this.log.error("parseMultiPartPost: Error parsing request", e);
}
}
}
Loading