[haiku-commits] Change in haiku[master]: FileRequest: Make Stop() cancel the request as soon as possible

  • From: Gerrit <review@xxxxxxxxxxxxxxxxxxx>
  • To: waddlesplash <waddlesplash@xxxxxxxxx>, haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 25 Jul 2020 10:06:36 +0000

From leorize <leorize+oss@xxxxxxxxxxx>:

leorize has uploaded this change for review. ( 
https://review.haiku-os.org/c/haiku/+/3071 ;)


Change subject: FileRequest: Make Stop() cancel the request as soon as possible
......................................................................

FileRequest: Make Stop() cancel the request as soon as possible

This commit implements a check for the flag raised by Stop() to cancel
a given request as soon as possible. Cancelled requests will return
B_INTERRUPTED regardless of whether the request has completed,
on par with how BHttpRequest is behaving at the moment.

Change-Id: Ia8a95b910cff158c710c5b2ed58b4675e705642e
---
M src/kits/network/libnetapi/FileRequest.cpp
A src/tests/kits/net/service/FileTest.cpp
A src/tests/kits/net/service/FileTest.h
M src/tests/kits/net/service/Jamfile
M src/tests/kits/net/service/ServiceKitTestAddon.cpp
5 files changed, 133 insertions(+), 7 deletions(-)



  git pull ssh://git.haiku-os.org:22/haiku refs/changes/71/3071/1

diff --git a/src/kits/network/libnetapi/FileRequest.cpp 
b/src/kits/network/libnetapi/FileRequest.cpp
index f8af655..82c5f35 100644
--- a/src/kits/network/libnetapi/FileRequest.cpp
+++ b/src/kits/network/libnetapi/FileRequest.cpp
@@ -79,12 +79,19 @@

                        fListener->HeadersReceived(this, fResult);

-                       ssize_t chunkSize;
+                       ssize_t chunkSize = 0;
                        char chunk[4096];
-                       while ((chunkSize = file.Read(chunk, sizeof(chunk))) > 
0) {
-                               fListener->DataReceived(this, chunk, 
transferredSize, chunkSize);
-                               transferredSize += chunkSize;
+                       while (!fQuit) {
+                               chunkSize = file.Read(chunk, sizeof(chunk));
+                               if (chunkSize > 0) {
+                                       fListener->DataReceived(this, chunk, 
transferredSize,
+                                               chunkSize);
+                                       transferredSize += chunkSize;
+                               } else
+                                       break;
                        }
+                       if (fQuit)
+                               return B_INTERRUPTED;
                        // Return error if we didn't transfer everything
                        if (transferredSize != size) {
                                if (chunkSize < 0)
@@ -122,7 +129,7 @@

        char name[B_FILE_NAME_LENGTH];
        BEntry entry;
-       while (directory.GetNextEntry(&entry) != B_ENTRY_NOT_FOUND) {
+       while (!fQuit && directory.GetNextEntry(&entry) != B_ENTRY_NOT_FOUND) {
                // We read directories using the EPLF (Easily Parsed List 
Format)
                // This happens to be one of the formats that WebKit can 
understand,
                // and it is not too hard to parse or generate.
@@ -160,7 +167,8 @@

        if (fListener != NULL)
                fListener->DownloadProgress(this, transferredSize, 
transferredSize);
-       fResult.SetLength(transferredSize);
+       if (!fQuit)
+               fResult.SetLength(transferredSize);

-       return B_OK;
+       return fQuit ? B_INTERRUPTED : B_OK;
 }
diff --git a/src/tests/kits/net/service/FileTest.cpp 
b/src/tests/kits/net/service/FileTest.cpp
new file mode 100644
index 0000000..71f68ce
--- /dev/null
+++ b/src/tests/kits/net/service/FileTest.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2020, Haiku, Inc.
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "FileTest.h"
+
+#include <stdlib.h>
+
+#include <File.h>
+#include <FileRequest.h>
+#include <Url.h>
+#include <UrlProtocolRoster.h>
+#include <UrlProtocolListener.h>
+
+#include <ThreadedTestCaller.h>
+#include <TestUtils.h>
+
+#include "TestServer.h"
+
+
+class StopTestListener : public BUrlProtocolListener {
+public:
+       StopTestListener() {}
+
+       void DataReceived(BUrlRequest *caller, const char*, off_t, ssize_t)
+       {
+               caller->Stop();
+       }
+};
+
+
+void
+FileTest::StopTest()
+{
+       StopTestListener listener;
+       char tmpl[] = "/tmp/filestoptestXXXXXX";
+       int fd = mkstemp(tmpl);
+       CHK(fd != -1);
+       close(fd);
+
+       BFile file(tmpl, O_WRONLY | O_CREAT);
+       CHK(file.InitCheck() == B_OK);
+       BString content;
+       /* number chosen to be larger than BFileRequest buffer, adjust as 
needed */
+       content.Append('f', 40960);
+
+       CHK(file.WriteExactly(content.String(), content.Length()) == B_OK);
+
+       BUrl url("file://");
+       url.SetPath(tmpl);
+       BUrlRequest *request = BUrlProtocolRoster::MakeRequest(url, &listener);
+       CHK(request != NULL);
+
+       thread_id thr = request->Run();
+       status_t dummy;
+       wait_for_thread(thr, &dummy);
+
+       CHK(request->Status() == B_INTERRUPTED);
+
+       delete request;
+
+       request = BUrlProtocolRoster::MakeRequest("file:///", &listener);
+       CHK(request != NULL);
+
+       thr = request->Run();
+       wait_for_thread(thr, &dummy);
+
+       CHK(request->Status() == B_INTERRUPTED);
+
+       delete request;
+}
+
+
+/* static */ void
+FileTest::AddTests(BTestSuite& parent)
+{
+       CppUnit::TestSuite *suite = new CppUnit::TestSuite("FileTest");
+
+       suite->addTest(new CppUnit::TestCaller<FileTest>("FileTest: Stop 
requests",
+               &FileTest::StopTest));
+
+       parent.addTest("FileTest", suite);
+}
diff --git a/src/tests/kits/net/service/FileTest.h 
b/src/tests/kits/net/service/FileTest.h
new file mode 100644
index 0000000..1c9bfd4
--- /dev/null
+++ b/src/tests/kits/net/service/FileTest.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2014-2020 Haiku, Inc.
+ * Distributed under the terms of the MIT License.
+ */
+
+#ifndef FILE_TEST_H
+#define FILE_TEST_H
+
+
+#include <Url.h>
+
+#include <TestCase.h>
+#include <TestSuite.h>
+
+#include <cppunit/TestSuite.h>
+#include <tools/cppunit/ThreadedTestCase.h>
+
+#include "TestServer.h"
+
+
+class FileTest : public BThreadedTestCase {
+public:
+                                               FileTest() {};
+
+                       void            StopTest();
+
+       static  void            AddTests(BTestSuite& suite);
+};
+
+
+#endif
diff --git a/src/tests/kits/net/service/Jamfile 
b/src/tests/kits/net/service/Jamfile
index de793aa..defd544 100644
--- a/src/tests/kits/net/service/Jamfile
+++ b/src/tests/kits/net/service/Jamfile
@@ -9,6 +9,7 @@
        DataTest.cpp
        HttpTest.cpp
        UrlTest.cpp
+       FileTest.cpp
        TestServer.cpp

        : be $(TARGET_NETWORK_LIBS) $(HAIKU_NETAPI_LIB) [ TargetLibstdc++ ]
diff --git a/src/tests/kits/net/service/ServiceKitTestAddon.cpp 
b/src/tests/kits/net/service/ServiceKitTestAddon.cpp
index d79c8d5..cce251b 100644
--- a/src/tests/kits/net/service/ServiceKitTestAddon.cpp
+++ b/src/tests/kits/net/service/ServiceKitTestAddon.cpp
@@ -11,6 +11,7 @@
 #include "DataTest.h"
 #include "HttpTest.h"
 #include "UrlTest.h"
+#include "FileTest.h"


 BTestSuite*
@@ -22,6 +23,7 @@
        UrlTest::AddTests(*suite);
        HttpTest::AddTests(*suite);
        DataTest::AddTests(*suite);
+       FileTest::AddTests(*suite);

        return suite;
 }

--
To view, visit https://review.haiku-os.org/c/haiku/+/3071
To unsubscribe, or for help writing mail filters, visit 
https://review.haiku-os.org/settings

Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: Ia8a95b910cff158c710c5b2ed58b4675e705642e
Gerrit-Change-Number: 3071
Gerrit-PatchSet: 1
Gerrit-Owner: leorize <leorize+oss@xxxxxxxxxxx>
Gerrit-MessageType: newchange

Other related posts:

  • » [haiku-commits] Change in haiku[master]: FileRequest: Make Stop() cancel the request as soon as possible - Gerrit