diff --git a/src/kits/network/libnetapi/FileRequest.cpp b/src/kits/network/libnetapi/FileRequest.cpp index f8af6555b4..82c5f35e00 100644 --- a/src/kits/network/libnetapi/FileRequest.cpp +++ b/src/kits/network/libnetapi/FileRequest.cpp @@ -79,12 +79,19 @@ BFileRequest::_ProtocolLoop() 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 @@ BFileRequest::_ProtocolLoop() 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 @@ BFileRequest::_ProtocolLoop() 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 0000000000..71f68cedd4 --- /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 + +#include +#include +#include +#include +#include + +#include +#include + +#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: 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 0000000000..1c9bfd4d73 --- /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 + +#include +#include + +#include +#include + +#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 de793aa8ea..defd5447a1 100644 --- a/src/tests/kits/net/service/Jamfile +++ b/src/tests/kits/net/service/Jamfile @@ -9,6 +9,7 @@ UnitTestLib servicekittest.so : 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 d79c8d5f89..cce251b5ee 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 @@ getTestSuite() UrlTest::AddTests(*suite); HttpTest::AddTests(*suite); DataTest::AddTests(*suite); + FileTest::AddTests(*suite); return suite; }