Repository: tomee
Updated Branches:
  refs/heads/master 3e2fe0af9 -> 481fc0516


TOMEE-1715 basic Part support in openejb-http


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/481fc051
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/481fc051
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/481fc051

Branch: refs/heads/master
Commit: 481fc05169a57af8fe52a7f0ed89bf9d77c57d27
Parents: 3e2fe0a
Author: Romain manni-Bucau <rmannibu...@gmail.com>
Authored: Fri Feb 19 19:04:22 2016 +0100
Committer: Romain manni-Bucau <rmannibu...@gmail.com>
Committed: Fri Feb 19 19:04:22 2016 +0100

----------------------------------------------------------------------
 server/openejb-http/pom.xml                     |   7 ++
 .../openejb/server/httpd/HttpRequestImpl.java   |  27 ++++-
 .../httpd/part/CommonsFileUploadPart.java       | 117 +++++++++++++++++++
 .../part/CommonsFileUploadPartFactory.java      |  91 +++++++++++++++
 4 files changed, 237 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/481fc051/server/openejb-http/pom.xml
----------------------------------------------------------------------
diff --git a/server/openejb-http/pom.xml b/server/openejb-http/pom.xml
index 630220c..a351213 100644
--- a/server/openejb-http/pom.xml
+++ b/server/openejb-http/pom.xml
@@ -139,6 +139,13 @@
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+
+    <dependency>
+      <groupId>commons-fileupload</groupId>
+      <artifactId>commons-fileupload</artifactId>
+      <version>1.3.1</version>
+      <optional>true</optional>
+    </dependency>
   </dependencies>
 </project>
 

http://git-wip-us.apache.org/repos/asf/tomee/blob/481fc051/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java
----------------------------------------------------------------------
diff --git 
a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java
 
b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java
index fa2428c..28a9f47 100644
--- 
a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java
+++ 
b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java
@@ -21,6 +21,7 @@ import org.apache.openejb.assembler.classic.Assembler;
 import org.apache.openejb.assembler.classic.WebAppInfo;
 import org.apache.openejb.core.WebContext;
 import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.server.httpd.part.CommonsFileUploadPartFactory;
 import org.apache.openejb.server.httpd.session.SessionManager;
 import org.apache.openejb.spi.SecurityService;
 import org.apache.openejb.util.ArrayEnumeration;
@@ -69,6 +70,7 @@ import javax.servlet.http.HttpSessionEvent;
 import javax.servlet.http.HttpUpgradeHandler;
 import javax.servlet.http.Part;
 
+import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
 
 /**
@@ -77,6 +79,7 @@ import static java.util.Collections.singletonList;
  */
 public class HttpRequestImpl implements HttpRequest {
     private static final String FORM_URL_ENCODED = 
"application/x-www-form-urlencoded";
+    private static final String MULTIPART_FORM_DATA = "multipart/form-data";
     private static final String TRANSFER_ENCODING = "Transfer-Encoding";
     private static final String CHUNKED = "chunked";
 
@@ -122,7 +125,7 @@ public class HttpRequestImpl implements HttpRequest {
      */
     private final Map<String, List<String>> parameters = new HashMap<>();
 
-    private final Map<String, Part> parts = new HashMap<>();
+    private volatile Collection<Part> parts;
 
     /**
      * Cookies sent from the client
@@ -217,7 +220,15 @@ public class HttpRequestImpl implements HttpRequest {
 
     @Override
     public Part getPart(String s) throws IOException, ServletException {
-        return parts.get(s);
+        getParts(); // ensure it is initialized
+        if (parts != null) {
+            for (final Part p : parts) {
+                if (s.equals(p.getName())) {
+                    return p;
+                }
+            }
+        }
+        return null;
     }
 
     @Override
@@ -227,7 +238,10 @@ public class HttpRequestImpl implements HttpRequest {
 
     @Override
     public Collection<Part> getParts() throws IOException, ServletException {
-        return parts.values();
+        if (parts == null) { // assume it is not init
+            parts = CommonsFileUploadPartFactory.read(this);
+        }
+        return parts;
     }
 
     public void noPathInfo() { // todo: enhance it
@@ -662,7 +676,7 @@ public class HttpRequestImpl implements HttpRequest {
         contentType = getHeader(HttpRequest.HEADER_CONTENT_TYPE);
 
         final boolean hasBody = hasBody();
-        if (hasBody && contentType != null && 
contentType.startsWith(FORM_URL_ENCODED)) {
+        if (hasBody && contentType != null && 
(contentType.startsWith(FORM_URL_ENCODED) || 
contentType.startsWith(MULTIPART_FORM_DATA))) {
             String rawParams;
 
             try {
@@ -696,7 +710,6 @@ public class HttpRequestImpl implements HttpRequest {
                     value = "";
 
                 formParams.put(name, value);
-                //System.out.println(name + ": " + value);
             }
         } else if (hasBody && CHUNKED.equals(headers.get(TRANSFER_ENCODING))) {
             try {
@@ -1029,6 +1042,10 @@ public class HttpRequestImpl implements HttpRequest {
                 new WebBeansFilter.AsynContextWrapper(asyncContext, 
servletRequest, webBeansContext) : asyncContext;
     }
 
+    public void addInternalParameter(final String key, final String val) {
+        parameters.put(key, asList(val));
+    }
+
     public String getParameter(String name) {
         final List<String> strings = parameters.get(name);
         return strings == null ? null : strings.iterator().next();

http://git-wip-us.apache.org/repos/asf/tomee/blob/481fc051/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/part/CommonsFileUploadPart.java
----------------------------------------------------------------------
diff --git 
a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/part/CommonsFileUploadPart.java
 
b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/part/CommonsFileUploadPart.java
new file mode 100644
index 0000000..a056360
--- /dev/null
+++ 
b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/part/CommonsFileUploadPart.java
@@ -0,0 +1,117 @@
+/*
+* 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.openejb.server.httpd.part;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.disk.DiskFileItem;
+
+import javax.servlet.http.Part;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+// highly inspired from tomcat
+public class CommonsFileUploadPart implements Part {
+    private final FileItem fileItem;
+    private final File location;
+
+    public CommonsFileUploadPart(final FileItem fileItem, final File location) 
{
+        this.fileItem = fileItem;
+        this.location = location;
+    }
+
+    @Override
+    public void delete() throws IOException {
+        fileItem.delete();
+    }
+
+    @Override
+    public String getContentType() {
+        return fileItem.getContentType();
+    }
+
+    @Override
+    public String getHeader(final String name) {
+        return fileItem.getHeaders().getHeader(name);
+    }
+
+    @Override
+    public Collection<String> getHeaderNames() {
+        if (fileItem instanceof DiskFileItem) {
+            final Set<String> headerNames = new LinkedHashSet<>();
+            final Iterator<String> iter = 
fileItem.getHeaders().getHeaderNames();
+            while (iter.hasNext()) {
+                headerNames.add(iter.next());
+            }
+            return headerNames;
+        }
+        return Collections.emptyList();
+    }
+
+    @Override
+    public Collection<String> getHeaders(final String name) {
+        final Set<String> headers = new LinkedHashSet<>();
+        final Iterator<String> iter = fileItem.getHeaders().getHeaders(name);
+        while (iter.hasNext()) {
+            headers.add(iter.next());
+        }
+        return headers;
+    }
+
+    @Override
+    public InputStream getInputStream() throws IOException {
+        return fileItem.getInputStream();
+    }
+
+    @Override
+    public String getName() {
+        return fileItem.getFieldName();
+    }
+
+    @Override
+    public long getSize() {
+        return fileItem.getSize();
+    }
+
+    @Override
+    public void write(final String fileName) throws IOException {
+        File file = new File(fileName);
+        if (!file.isAbsolute()) {
+            file = new File(location, fileName);
+        }
+        try {
+            fileItem.write(file);
+        } catch (Exception e) {
+            throw new IOException(e);
+        }
+    }
+
+    public String getString(final String encoding) throws 
UnsupportedEncodingException {
+        return fileItem.getString(encoding);
+    }
+
+    @Override
+    public String getSubmittedFileName() {
+        return fileItem.getName();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/481fc051/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/part/CommonsFileUploadPartFactory.java
----------------------------------------------------------------------
diff --git 
a/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/part/CommonsFileUploadPartFactory.java
 
b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/part/CommonsFileUploadPartFactory.java
new file mode 100644
index 0000000..309498d
--- /dev/null
+++ 
b/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/part/CommonsFileUploadPartFactory.java
@@ -0,0 +1,91 @@
+package org.apache.openejb.server.httpd.part;
+
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileUploadException;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.apache.commons.fileupload.servlet.ServletRequestContext;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.server.httpd.HttpRequestImpl;
+
+import javax.servlet.http.Part;
+import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+
+// [fileupload] is optional so using a class to lazy load the deps
+public final class CommonsFileUploadPartFactory {
+    private static final File REPO;
+
+    static { // TODO: move this config in http service if this code is useful
+        String repo = 
SystemInstance.get().getProperty("tomee.embedded.http.file.repository");
+        if (repo == null) {
+            for (final String potential : asList("work", "temp", "target", 
"build")) {
+                try {
+                    final File directory = 
SystemInstance.get().getBase().getDirectory(potential);
+                    if (directory.isDirectory()) {
+                        repo = directory.getAbsolutePath();
+                        break;
+                    }
+                } catch (IOException e) {
+                    // try next
+                }
+            }
+        }
+        REPO = new File(repo == null ? "." : repo);
+    }
+
+    private CommonsFileUploadPartFactory() {
+        // no-op
+    }
+
+    public static Collection<Part> read(final HttpRequestImpl request) { // 
mainly for testing
+        // Create a new file upload handler
+        final DiskFileItemFactory factory = new DiskFileItemFactory();
+        factory.setRepository(REPO);
+
+        final ServletFileUpload upload = new ServletFileUpload();
+        upload.setFileItemFactory(factory);
+
+        final List<Part> parts = new ArrayList<>();
+        try {
+            final List<FileItem> items = upload.parseRequest(new 
ServletRequestContext(request));
+            final String enc = request.getCharacterEncoding();
+            for (final FileItem item : items) {
+                final CommonsFileUploadPart part = new 
CommonsFileUploadPart(item, null);
+                parts.add(part);
+                if (part.getSubmittedFileName() == null) {
+                    String name = part.getName();
+                    String value = null;
+                    try {
+                        String encoding = request.getCharacterEncoding();
+                        if (encoding == null) {
+                            if (enc == null) {
+                                encoding = "UTF-8";
+                            } else {
+                                encoding = enc;
+                            }
+                        }
+                        value = part.getString(encoding);
+                    } catch (final UnsupportedEncodingException uee) {
+                        try {
+                            value = part.getString("UTF-8");
+                        } catch (final UnsupportedEncodingException e) {
+                            // not possible
+                        }
+                    }
+                    request.addInternalParameter(name, value);
+                }
+            }
+
+            return parts;
+        } catch (final FileUploadException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+}

Reply via email to