You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ro...@apache.org on 2017/01/11 08:49:59 UTC

[1/2] james-project git commit: JAMES-1871: Canceling JMAP uploads should not return an error

Repository: james-project
Updated Branches:
  refs/heads/master 131c01148 -> 1602d26db


JAMES-1871: Canceling JMAP uploads should not return an error


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/89800605
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/89800605
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/89800605

Branch: refs/heads/master
Commit: 8980060561940cda6fe1140c2ef992f10a874468
Parents: 131c011
Author: Quynh Nguyen <qn...@linagora.com>
Authored: Tue Dec 27 11:15:39 2016 +0700
Committer: Quynh Nguyen <qn...@linagora.com>
Committed: Wed Jan 11 10:02:30 2017 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/jmap/UploadServlet.java  | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/89800605/server/protocols/jmap/src/main/java/org/apache/james/jmap/UploadServlet.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/UploadServlet.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/UploadServlet.java
index 873bf5e..d858698 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/UploadServlet.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/UploadServlet.java
@@ -21,6 +21,7 @@ package org.apache.james.jmap;
 import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
 import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
 
+import java.io.EOFException;
 import java.io.IOException;
 
 import javax.inject.Inject;
@@ -54,13 +55,23 @@ public class UploadServlet extends HttpServlet {
         } else {
             try {
                 uploadHandler.handle(contentType, req.getInputStream(), getMailboxSession(req), resp);
-            } catch (IOException | MailboxException e) {
-                LOGGER.error("Error while uploading content", e);
-                resp.setStatus(SC_INTERNAL_SERVER_ERROR);
+            } catch (IOException e) {
+                if (e instanceof EOFException) {
+                    LOGGER.info("An upload has been canceled before the end", e);
+                } else {
+                    internalServerError(resp, e);
+                }
+            } catch (MailboxException e) {
+                internalServerError(resp, e);
             }
         }
     }
 
+    private void internalServerError(HttpServletResponse resp, Exception e) {
+        LOGGER.error("Error while uploading content", e);
+        resp.setStatus(SC_INTERNAL_SERVER_ERROR);
+    }
+
     private MailboxSession getMailboxSession(HttpServletRequest req) {
         return (MailboxSession) req.getAttribute(AuthenticationFilter.MAILBOX_SESSION);
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[2/2] james-project git commit: JAMES-1871 Integration test on canceling a JMAP upload

Posted by ro...@apache.org.
JAMES-1871 Integration test on canceling a JMAP upload


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/1602d26d
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/1602d26d
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/1602d26d

Branch: refs/heads/master
Commit: 1602d26db027edf21546704d6006d80f6b5e12c2
Parents: 8980060
Author: Antoine Duprat <ad...@linagora.com>
Authored: Tue Jan 3 11:56:29 2017 +0100
Committer: Quynh Nguyen <qn...@linagora.com>
Committed: Wed Jan 11 10:02:55 2017 +0700

----------------------------------------------------------------------
 .../james/util/CountDownConsumeInputStream.java | 46 ++++++++++++++++++
 .../integration/cucumber/UploadStepdefs.java    | 51 +++++++++++++++++++-
 .../resources/cucumber/UploadEndpoint.feature   |  5 ++
 3 files changed, 101 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/1602d26d/server/container/util/src/main/java/org/apache/james/util/CountDownConsumeInputStream.java
----------------------------------------------------------------------
diff --git a/server/container/util/src/main/java/org/apache/james/util/CountDownConsumeInputStream.java b/server/container/util/src/main/java/org/apache/james/util/CountDownConsumeInputStream.java
new file mode 100644
index 0000000..dbf952d
--- /dev/null
+++ b/server/container/util/src/main/java/org/apache/james/util/CountDownConsumeInputStream.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.james.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.CountDownLatch;
+
+public class CountDownConsumeInputStream extends InputStream {
+    private static final int RETURNED_VALUE = 0;
+
+    private final CountDownLatch startSignal;
+
+    public CountDownConsumeInputStream(CountDownLatch startSignal) {
+        this.startSignal = startSignal;
+    }
+
+    public CountDownLatch getStartSignal() {
+        return startSignal;
+    }
+
+    @Override
+    public int read() throws IOException {
+        if (startSignal.getCount() > 0) {
+            return RETURNED_VALUE;
+        }
+        return -1;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/1602d26d/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/UploadStepdefs.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/UploadStepdefs.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/UploadStepdefs.java
index 8bcfca2..4c7d8a5 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/UploadStepdefs.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/UploadStepdefs.java
@@ -24,21 +24,27 @@ import static org.assertj.core.api.Assertions.assertThat;
 import java.io.BufferedInputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
 
 import javax.inject.Inject;
 
 import org.apache.http.Header;
 import org.apache.http.HttpResponse;
+import org.apache.http.client.fluent.Async;
+import org.apache.http.client.fluent.Content;
 import org.apache.http.client.fluent.Executor;
 import org.apache.http.client.fluent.Request;
+import org.apache.http.concurrent.FutureCallback;
 import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.james.jmap.api.access.AccessToken;
+import org.apache.james.util.CountDownConsumeInputStream;
 import org.apache.james.util.ZeroedInputStream;
 
 import com.google.common.base.Charsets;
 import com.jayway.jsonpath.DocumentContext;
 import com.jayway.jsonpath.JsonPath;
-
+import cucumber.api.java.en.Given;
 import cucumber.api.java.en.Then;
 import cucumber.api.java.en.When;
 import cucumber.runtime.java.guice.ScenarioScoped;
@@ -53,6 +59,8 @@ public class UploadStepdefs {
     private final MainStepdefs mainStepdefs;
     private final URI uploadUri;
     private HttpResponse response;
+    private Future<Content> async;
+    private boolean isCanceled;
 
     @Inject
     private UploadStepdefs(UserStepdefs userStepdefs, MainStepdefs mainStepdefs) throws URISyntaxException {
@@ -61,6 +69,37 @@ public class UploadStepdefs {
         uploadUri = mainStepdefs.baseUri().setPath("/upload").build();
     }
 
+    @Given("^\"([^\"]*)\" is starting uploading a content$")
+    public void userStartUploadContent(String username) throws Throwable {
+        AccessToken accessToken = userStepdefs.tokenByUser.get(username);
+
+        CountDownLatch startSignal = new CountDownLatch(2);
+        CountDownConsumeInputStream bodyStream = new CountDownConsumeInputStream(startSignal);
+        Request request = Request.Post(uploadUri)
+            .bodyStream(new BufferedInputStream(bodyStream, _1M), org.apache.http.entity.ContentType.DEFAULT_BINARY);
+        if (accessToken != null) {
+            request.addHeader("Authorization", accessToken.serialize());
+        }
+        async = Async.newInstance().execute(request, new FutureCallback<Content>() {
+            
+            @Override
+            public void failed(Exception ex) {
+            }
+            
+            @Override
+            public void completed(Content result) {
+            }
+            
+            @Override
+            public void cancelled() {
+                bodyStream.getStartSignal().countDown();
+                if (bodyStream.getStartSignal().getCount() == 1) {
+                    isCanceled = true;
+                }
+            }
+        });
+    }
+
     @When("^\"([^\"]*)\" upload a content$")
     public void userUploadContent(String username) throws Throwable {
         AccessToken accessToken = userStepdefs.tokenByUser.get(username);
@@ -104,6 +143,11 @@ public class UploadStepdefs {
         response = request.execute().returnResponse();
     }
 
+    @Then("^the user disconnect$")
+    public void stopUpload() throws Throwable {
+        async.cancel(true);
+    }
+
     @Then("^the user should receive an authorized response$")
     public void httpAuthorizedStatus() throws Exception {
         assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200);
@@ -148,4 +192,9 @@ public class UploadStepdefs {
         response = request.execute().returnResponse();
         httpAuthorizedStatus();
     }
+
+    @Then("^the request should be marked as canceled$")
+    public void requestHasBeenCanceled() throws Exception {
+        assertThat(isCanceled).isTrue();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/1602d26d/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/UploadEndpoint.feature
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/UploadEndpoint.feature b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/UploadEndpoint.feature
index 4edb949..6f82ada 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/UploadEndpoint.feature
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/UploadEndpoint.feature
@@ -23,6 +23,11 @@ Feature: An upload endpoint should be available to upload contents
     When "username@domain.tld" upload a too big content
     Then the user should receive a request entity too large response
 
+  Scenario: Stoping an upload should work
+    Given "username@domain.tld" is starting uploading a content
+    When the user disconnect
+    Then the request should be marked as canceled
+
   Scenario: Uploading a content being authenticated
     When "username@domain.tld" upload a content
     Then the user should receive a created response


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org