[KARAF-6597] Add servlet upload example and corresponding itest.
diff --git a/examples/karaf-servlet-example/README.md b/examples/karaf-servlet-example/README.md
index c1d683f..b5f704d 100644
--- a/examples/karaf-servlet-example/README.md
+++ b/examples/karaf-servlet-example/README.md
@@ -84,4 +84,20 @@
 
 Whatever feature you use, you can access the servlet on the following URL:
 
-[http://localhost:8181/servlet-example]
\ No newline at end of file
+[http://localhost:8181/servlet-example]
+
+## Upload Servlet
+
+You can also find a upload servlet example using multipart data.
+
+You can install it with:
+
+```
+karaf@root()> feature:install karaf-servlet-example-upload
+```
+
+Then, you can use `curl` to upload data via this servlet:
+
+```
+curl --progress-bar -v -k -F file=/my/file http://127.0.0.1:8181/upload-example
+```
\ No newline at end of file
diff --git a/examples/karaf-servlet-example/karaf-servlet-example-features/src/main/feature/feature.xml b/examples/karaf-servlet-example/karaf-servlet-example-features/src/main/feature/feature.xml
index 1b1af79..1bbfa94 100644
--- a/examples/karaf-servlet-example/karaf-servlet-example-features/src/main/feature/feature.xml
+++ b/examples/karaf-servlet-example/karaf-servlet-example-features/src/main/feature/feature.xml
@@ -42,4 +42,10 @@
         <bundle>mvn:org.apache.karaf.examples/karaf-servlet-example-scr/${project.version}</bundle>
     </feature>
 
+    <feature name="karaf-servlet-example-upload" version="${project.version}">
+        <feature prerequisite="true">scr</feature>
+        <feature prerequisite="true">http</feature>
+        <bundle>mvn:org.apache.karaf.examples/karaf-servlet-example-upload/${project.version}</bundle>
+    </feature>
+
 </features>
diff --git a/examples/karaf-servlet-example/karaf-servlet-example-upload/pom.xml b/examples/karaf-servlet-example/karaf-servlet-example-upload/pom.xml
new file mode 100644
index 0000000..f46f534
--- /dev/null
+++ b/examples/karaf-servlet-example/karaf-servlet-example-upload/pom.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.karaf.examples</groupId>
+        <artifactId>karaf-servlet-example</artifactId>
+        <version>4.3.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>karaf-servlet-example-upload</artifactId>
+    <name>Apache Karaf :: Examples :: Servlet :: Upload</name>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>3.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi.cmpn</artifactId>
+            <version>6.0.0</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/examples/karaf-servlet-example/karaf-servlet-example-upload/src/main/java/org/apache/karaf/examples/servlet/upload/Component.java b/examples/karaf-servlet-example/karaf-servlet-example-upload/src/main/java/org/apache/karaf/examples/servlet/upload/Component.java
new file mode 100644
index 0000000..ffa208b
--- /dev/null
+++ b/examples/karaf-servlet-example/karaf-servlet-example-upload/src/main/java/org/apache/karaf/examples/servlet/upload/Component.java
@@ -0,0 +1,46 @@
+/*
+ *  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.karaf.examples.servlet.upload;
+
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.http.HttpService;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+@org.osgi.service.component.annotations.Component
+public class Component {
+
+    @Reference
+    protected HttpService httpService;
+
+    @Activate
+    public void activate() throws Exception {
+        final String tmpDir = System.getProperty("java.io.tmpdir");
+        final Path uploadPath = Paths.get(tmpDir, "karaf", "upload");
+        uploadPath.toFile().mkdirs();
+        httpService.registerServlet("/upload-example", new UploadServlet(uploadPath), null, null);
+    }
+
+    @Deactivate
+    public void deactivate() throws Exception {
+        httpService.unregister("/upload-example");
+    }
+
+}
diff --git a/examples/karaf-servlet-example/karaf-servlet-example-upload/src/main/java/org/apache/karaf/examples/servlet/upload/UploadServlet.java b/examples/karaf-servlet-example/karaf-servlet-example-upload/src/main/java/org/apache/karaf/examples/servlet/upload/UploadServlet.java
new file mode 100644
index 0000000..81329f8
--- /dev/null
+++ b/examples/karaf-servlet-example/karaf-servlet-example-upload/src/main/java/org/apache/karaf/examples/servlet/upload/UploadServlet.java
@@ -0,0 +1,70 @@
+/*
+ *  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.karaf.examples.servlet.upload;
+
+import javax.servlet.MultipartConfigElement;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.Part;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.Map;
+
+public class UploadServlet extends HttpServlet {
+
+    /** The size threshold after which the file will be written to disk. */
+    private static final int FILE_SIZE_THRESHOLD = 1024 * 1024 * 2;
+
+    /** The maximum size allowed for uploaded files (-1L means unlimited). */
+    private static final long MAX_FILE_SIZE = 1024 * 1024 * 1024;
+
+    /** The maximum size allowed for "multipart/form-data" requests (-1L means unlimited). */
+    private static final long MAX_REQUEST_SIZE = 1024 * 1024 * 1024;
+
+    private final File tempDir;
+
+    public UploadServlet(final Path tempDir) {
+        this.tempDir = tempDir.toFile();
+    }
+
+    @Override
+    public void init() throws ServletException {
+        final MultipartConfigElement multipartConfigElement = new MultipartConfigElement(tempDir.getAbsolutePath(), MAX_FILE_SIZE, MAX_REQUEST_SIZE, FILE_SIZE_THRESHOLD);
+        for (final Map.Entry<String, ? extends ServletRegistration> entry : getServletContext().getServletRegistrations()
+                .entrySet()) {
+            final ServletRegistration reg = entry.getValue();
+            if (reg == null) {
+                continue;
+            }
+            if (reg instanceof ServletRegistration.Dynamic) {
+                final ServletRegistration.Dynamic regDyn = (ServletRegistration.Dynamic) reg;
+                regDyn.setMultipartConfig(multipartConfigElement);
+            }
+        }
+    }
+
+    @Override
+    public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
+        final Collection<Part> parts = request.getParts();
+    }
+
+}
diff --git a/examples/karaf-servlet-example/pom.xml b/examples/karaf-servlet-example/pom.xml
index d1c0806..58af9b1 100644
--- a/examples/karaf-servlet-example/pom.xml
+++ b/examples/karaf-servlet-example/pom.xml
@@ -37,6 +37,7 @@
         <module>karaf-servlet-example-registration</module>
         <module>karaf-servlet-example-blueprint</module>
         <module>karaf-servlet-example-scr</module>
+        <module>karaf-servlet-example-upload</module>
         <module>karaf-servlet-example-features</module>
     </modules>
 
diff --git a/itests/test/src/test/java/org/apache/karaf/itests/examples/ServletExampleTest.java b/itests/test/src/test/java/org/apache/karaf/itests/examples/ServletExampleTest.java
index 4ef1037..27c541a 100644
--- a/itests/test/src/test/java/org/apache/karaf/itests/examples/ServletExampleTest.java
+++ b/itests/test/src/test/java/org/apache/karaf/itests/examples/ServletExampleTest.java
@@ -17,6 +17,7 @@
 package org.apache.karaf.itests.examples;
 
 import org.apache.karaf.itests.BaseTest;
+import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.ops4j.pax.exam.junit.PaxExam;
@@ -24,7 +25,14 @@
 import org.ops4j.pax.exam.spi.reactors.PerMethod;
 
 import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
 import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
 import java.net.HttpURLConnection;
 import java.net.URL;
 
@@ -97,4 +105,59 @@
         verify();
     }
 
+    @Test
+    public void testUploadServlet() throws Exception {
+        setup();
+
+        installAndAssertFeature("karaf-servlet-example-upload");
+
+        String command = executeCommand("http:list");
+        while (!command.contains("upload-example")) {
+            Thread.sleep(200);
+            command = executeCommand("http:list");
+        }
+        System.out.println(command);
+
+        File file = new File(System.getProperty("karaf.data"), "test.txt");
+        FileWriter fileWriter = new FileWriter(file);
+        fileWriter.write("test");
+        fileWriter.flush();
+        fileWriter.close();
+
+        URL url = new URL("http://localhost:" + getHttpPort() + "/upload-example");
+        String boundary = "===" + System.currentTimeMillis() + "===";
+        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+        connection.setRequestMethod("POST");
+        connection.setUseCaches(false);
+        connection.setDoInput(true);
+        connection.setDoOutput(true);
+        connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
+
+        OutputStream outputStream = connection.getOutputStream();
+
+        PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream), true);
+        writer.append("--" + boundary).append("\r\n");
+        writer.append("Content-Disposition: form-data; name=\"test\"; filename=\"test.txt\"").append("\r\n");
+        writer.append("Content-Type: text/plain; charset=UTF-8").append("\r\n");
+        writer.append("Content-Transfer-Encoding: binary").append("\r\n");
+        writer.append("\r\n");
+        writer.flush();
+
+        FileInputStream fileInputStream = new FileInputStream(file);
+        byte[] buffer = new byte[1024];
+        int bytesRead = -1;
+        while ((bytesRead = fileInputStream.read(buffer)) != -1) {
+            outputStream.write(buffer, 0, bytesRead);
+        }
+        outputStream.flush();
+        fileInputStream.close();
+        writer.append("\r\n");
+        writer.append("\r\n");
+        writer.append("--" + boundary + "--").append("\r\n");
+        writer.flush();
+        writer.close();
+
+        Assert.assertEquals(200, connection.getResponseCode());
+    }
+
 }
diff --git a/pom.xml b/pom.xml
index 24100fb..ac7d4da 100644
--- a/pom.xml
+++ b/pom.xml
@@ -284,7 +284,7 @@
         <pax.base.version>1.5.1</pax.base.version>
         <pax.swissbox.version>1.8.3</pax.swissbox.version>
         <pax.url.version>2.6.2</pax.url.version>
-        <pax.web.version>7.2.13</pax.web.version>
+        <pax.web.version>7.2.14-SNAPSHOT</pax.web.version>
         <pax.tinybundle.version>3.0.0</pax.tinybundle.version>
         <pax.jdbc.version>1.4.4</pax.jdbc.version>
         <pax.jms.version>1.0.6</pax.jms.version>