[ https://issues.apache.org/jira/browse/WICKET-7033?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17711089#comment-17711089 ]
ASF GitHub Bot commented on WICKET-7033: ---------------------------------------- martin-g commented on code in PR #571: URL: https://github.com/apache/wicket/pull/571#discussion_r1163222718 ########## wicket-core/src/main/java/org/apache/wicket/markup/html/form/upload/resource/FileUploadToResourceField.java: ########## @@ -0,0 +1,414 @@ +/* + * 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. + */ +package org.apache.wicket.markup.html.form.upload.resource; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import org.apache.commons.io.IOUtils; +import org.apache.wicket.Session; +import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.AjaxUtils; +import org.apache.wicket.core.request.handler.IPartialPageRequestHandler; +import org.apache.wicket.markup.head.IHeaderResponse; +import org.apache.wicket.markup.head.JavaScriptHeaderItem; +import org.apache.wicket.markup.head.OnDomReadyHeaderItem; +import org.apache.wicket.markup.html.form.upload.FileUpload; +import org.apache.wicket.markup.html.form.upload.FileUploadField; +import org.apache.wicket.model.IModel; +import org.apache.wicket.request.cycle.RequestCycle; +import org.apache.wicket.request.mapper.parameter.PageParameters; +import org.apache.wicket.request.resource.JavaScriptResourceReference; +import org.apache.wicket.resource.CoreLibrariesContributor; +import com.github.openjson.JSONArray; +import com.github.openjson.JSONObject; + +/** + * Implementation of FileUploadField capable to uploading a file into a wicket mounted resource. + * This field does not require a {@link org.apache.wicket.markup.html.form.Form}, and field by itself + * does to upload of the file via the {@link #startUpload(IPartialPageRequestHandler)} method. See wicket examples. + */ +public abstract class FileUploadToResourceField extends FileUploadField +{ + + /** + * Info regarding an upload. + */ + public static final class UploadInfo + { + private File file; + private final String clientFileName; + + private final long size; + + private final String contentType; + + public UploadInfo(String clientFileName, long size, String contentType) + { + this.clientFileName = clientFileName; + this.size = size; + this.contentType = contentType; + } + + public File getFile() + { + return file; + } + + public void setFile(File file) + { + this.file = file; + } + + public String getClientFileName() + { + return clientFileName; + } + + public long getSize() + { + return size; + } + + public String getContentType() + { + return contentType; + } + + @Override + public boolean equals(Object o) + { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + UploadInfo fileInfo = (UploadInfo) o; + return Objects.equals(clientFileName, fileInfo.clientFileName); + } + + /** + * @return the bytes associated with the upload. + */ + public byte[] get() + { + byte[] fileData = new byte[(int) getSize()]; + InputStream fis = null; + + try + { + fis = new FileInputStream(file); + IOUtils.readFully(fis, fileData); + } + catch (IOException e) + { + fileData = null; + } + finally + { + IOUtils.closeQuietly(fis); + } + + return fileData; + } + + @Override + public int hashCode() + { + return Objects.hash(clientFileName); + } + + public static List<UploadInfo> fromJson(String json) + { + List<UploadInfo> infos = new ArrayList<>(); + JSONArray jsonArray = new JSONArray(json); + for (int i = 0; i < jsonArray.length(); i++) + { + JSONObject jsonObject = jsonArray.getJSONObject(i); + infos.add(new UploadInfo(jsonObject.getString("clientFileName"), jsonObject.getLong("size"), jsonObject.getString("contentType"))); + } + return infos; + } + } + + private static final JavaScriptResourceReference JS = new JavaScriptResourceReference(FileUploadToResourceField.class, "FileUploadToResourceField.js"); + + public static String UPLOAD_CANCELED = "upload.canceled"; + + + private static abstract class FileModel implements IModel<List<UploadInfo>> + { + + @Override + public List<UploadInfo> getObject() + { + List<UploadInfo> fileInfos = getFileInfos(); + for (UploadInfo uploadInfo : fileInfos){ + uploadInfo.setFile(fileManager().getFile(getIdentifier(), uploadInfo.clientFileName)); + } + return fileInfos; + } + + @Override + public void setObject(List<UploadInfo> object) + { + throw new UnsupportedOperationException("setObject not supported"); + } + + protected abstract IUploadsFileManager fileManager(); + + protected abstract String getIdentifier(); + protected abstract List<UploadInfo> getFileInfos(); + } + + private final AbstractDefaultAjaxBehavior ajaxBehavior; + + private transient List<UploadInfo> fileInfos; + + public FileUploadToResourceField(String id) { + super(id); + setOutputMarkupId(true); + setMarkupId("WRFUF" + getUserId() + System.currentTimeMillis()); + setDefaultModel(new FileModel() { + @Override + protected IUploadsFileManager fileManager() { + return FileUploadToResourceField.this.fileManager(); + } + + @Override + protected String getIdentifier() + { + return FileUploadToResourceField.this.getMarkupId(); + } + + @Override + protected List<UploadInfo> getFileInfos() + { + return fileInfos; + } + }); + ajaxBehavior = new AbstractDefaultAjaxBehavior() + { + @Override + protected void respond(AjaxRequestTarget target) + { + boolean success = RequestCycle.get().getRequest().getRequestParameters().getParameterValue("success").toBoolean(false); + if (success) { + String filesIfo = RequestCycle.get().getRequest().getRequestParameters().getParameterValue("filesInfo").toString(); + fileInfos = UploadInfo.fromJson(filesIfo); + onUploadSuccess(target, getFileInfos()); + if (deleteFilesAfterUpload()) + { + for (UploadInfo uploadInfo : fileInfos) + { + fileManager().deleteFile(getMarkupId(), uploadInfo.clientFileName); Review Comment: Have you tested with `../../../etc/passwd` ? > add support to uploading to a resource > -------------------------------------- > > Key: WICKET-7033 > URL: https://issues.apache.org/jira/browse/WICKET-7033 > Project: Wicket > Issue Type: New Feature > Components: wicket > Reporter: Ernesto Reinaldo Barreiro > Assignee: Ernesto Reinaldo Barreiro > Priority: Major > Fix For: 10.0.0, 9.14.0 > > > Add support for the following: > * Upload to a resource in an asynchronous non page blocking request > * Add an optional way to block the user from leaving the page while the > upload is happening > * Ways to cancel the upload > * Adapt the upload progress bar to work with this new "component" and improve > its code as in some corner cases it is producing client side errors (I > created an issue for that some time ago). > * Maybe useful too: create a web socket based progress bar, as the upload > progress bar now works pulling the server every second. > * Also to add an example to wicket-examples that uses a smart JS uploader, > like in the blog > (https://github.com/martin-g/blogs/blob/master/file-upload/). This way you > will verify that the new APIs are easily extendable. -- This message was sent by Atlassian Jira (v8.20.10#820010)