-
Notifications
You must be signed in to change notification settings - Fork 18
SLING-13202 Remove dependency on commons-fileupload #75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 5 commits
ac00012
5aca587
bedd1f5
39c4d72
4f84a18
6efb03f
5020c47
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,9 +20,10 @@ | |
|
|
||
| import java.io.IOException; | ||
| import java.io.InputStream; | ||
| import java.io.UncheckedIOException; | ||
| import java.io.UnsupportedEncodingException; | ||
|
|
||
| import org.apache.commons.fileupload.disk.DiskFileItem; | ||
| import jakarta.servlet.http.Part; | ||
|
|
||
| /** | ||
| * The <code>MultipartRequestParameter</code> represents a request parameter | ||
|
|
@@ -34,33 +35,38 @@ | |
| */ | ||
| public class MultipartRequestParameter extends AbstractRequestParameter { | ||
|
|
||
| private final DiskFileItem delegatee; | ||
| private final Part delegatee; | ||
|
|
||
| private String encodedFileName; | ||
|
|
||
| private String cachedValue; | ||
|
|
||
| public MultipartRequestParameter(DiskFileItem delegatee) { | ||
| super(delegatee.getFieldName(), null); | ||
| public MultipartRequestParameter(Part delegatee) { | ||
| super(delegatee.getName(), null); | ||
| this.delegatee = delegatee; | ||
| } | ||
|
|
||
| void dispose() throws IOException { | ||
| this.delegatee.delete(); | ||
| } | ||
|
|
||
| DiskFileItem getFileItem() { | ||
| Part getPart() { | ||
| return this.delegatee; | ||
| } | ||
|
|
||
| @Override | ||
| void setEncoding(String encoding) { | ||
| super.setEncoding(encoding); | ||
| cachedValue = null; | ||
| encodedFileName = null; | ||
| } | ||
|
|
||
| public byte[] get() { | ||
| return this.delegatee.get(); | ||
| try { | ||
| return getInputStream().readAllBytes(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method re-reads the part on every call and never closes the stream. I will also suggest caching the content (https://github.com/apache/commons-fileupload/blob/FILEUPLOAD_1_3_1/src/main/java/org/apache/commons/fileupload/disk/DiskFileItem.java#L302)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch. I'll change this to a try-with-resources block to make sure the steam is closed. I think caching the bytes would be redundant and a premature optimization? And what if the file is really big? Reading the stream on demand seems safer and lets the container spool it from memory or disk. |
||
| } catch (IOException e) { | ||
| throw new UncheckedIOException(e); | ||
| } | ||
| } | ||
|
|
||
| public String getContentType() { | ||
|
|
@@ -72,8 +78,8 @@ public InputStream getInputStream() throws IOException { | |
| } | ||
|
|
||
| public String getFileName() { | ||
| if (this.encodedFileName == null && this.delegatee.getName() != null) { | ||
| String tmpFileName = this.delegatee.getName(); | ||
| if (this.encodedFileName == null && this.delegatee.getSubmittedFileName() != null) { | ||
| String tmpFileName = this.delegatee.getSubmittedFileName(); | ||
| if (this.getEncoding() != null) { | ||
| try { | ||
| byte[] rawName = tmpFileName.getBytes(Util.ENCODING_DIRECT); | ||
|
|
@@ -117,15 +123,16 @@ public String getString() { | |
| return this.cachedValue; | ||
| } | ||
|
|
||
| return this.delegatee.getString(); | ||
| return new String(this.get()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This now uses the JVM platform default charset. Same upload returns different strings on Linux UTF-8 vs Windows.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I was confused by the comment above that that said "only apply encoding in the case of a form field". If the DiskFileItem did do some other encoding, then I can do the same there. But I am not sure what the practical use case is for needing the file content as a string. |
||
| } | ||
|
|
||
| public String getString(String enc) throws UnsupportedEncodingException { | ||
| return new String(this.get(), enc); | ||
| } | ||
|
|
||
| public boolean isFormField() { | ||
| return this.delegatee.isFormField(); | ||
| // If getSubmittedFileName() returns null, it is likely a regular form field | ||
| return this.delegatee.getSubmittedFileName() == null; | ||
| } | ||
|
|
||
| public String toString() { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: do we need transient?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without this modifier, sonar reports it as a violation of rule "java:S1948" with this reason:
Fields in a "Serializable" class should either be transient or serializableThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally think that this we should ignore such default sonar reports. While this makes sense in general for Serializable objects, it does imho not make sense for Servlets (or any other service). These objects will never be serialized and therefore this just clutters the code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't bother me either way which is why I usually just change it to satisfy sonar. I have no idea how I would go about changing the sonar rules for specific "serializable" types for this or other sling projects. Please tell me how I would accomplish that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no idea, but I wouldnt blindly apply sonar suggestions and just apply the ones which make sense to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cziegeler That's the mindset that leads to projects having hundreds or thousands of unresolved warnings. When it gets to that state the real problems get lost in the noise. So I always make a best effort to have all the code I work on have no warnings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have seen dozens of such changes in general which actually made the code worse just to get rid off warnings in some tool. Lets agree that transient in this case is not needed, but it doesnt hurt either. So lets just move on..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comments in SLING-10506.