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 Reviewed-on: https://review.haiku-os.org/c/haiku/+/3071 Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
5b98fa06d5
commit
1f569db086
@ -79,12 +79,19 @@ BFileRequest::_ProtocolLoop()
|
|||||||
|
|
||||||
fListener->HeadersReceived(this, fResult);
|
fListener->HeadersReceived(this, fResult);
|
||||||
|
|
||||||
ssize_t chunkSize;
|
ssize_t chunkSize = 0;
|
||||||
char chunk[4096];
|
char chunk[4096];
|
||||||
while ((chunkSize = file.Read(chunk, sizeof(chunk))) > 0) {
|
while (!fQuit) {
|
||||||
fListener->DataReceived(this, chunk, transferredSize, chunkSize);
|
chunkSize = file.Read(chunk, sizeof(chunk));
|
||||||
transferredSize += chunkSize;
|
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
|
// Return error if we didn't transfer everything
|
||||||
if (transferredSize != size) {
|
if (transferredSize != size) {
|
||||||
if (chunkSize < 0)
|
if (chunkSize < 0)
|
||||||
@ -122,7 +129,7 @@ BFileRequest::_ProtocolLoop()
|
|||||||
|
|
||||||
char name[B_FILE_NAME_LENGTH];
|
char name[B_FILE_NAME_LENGTH];
|
||||||
BEntry entry;
|
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)
|
// We read directories using the EPLF (Easily Parsed List Format)
|
||||||
// This happens to be one of the formats that WebKit can understand,
|
// This happens to be one of the formats that WebKit can understand,
|
||||||
// and it is not too hard to parse or generate.
|
// and it is not too hard to parse or generate.
|
||||||
@ -160,7 +167,8 @@ BFileRequest::_ProtocolLoop()
|
|||||||
|
|
||||||
if (fListener != NULL)
|
if (fListener != NULL)
|
||||||
fListener->DownloadProgress(this, transferredSize, transferredSize);
|
fListener->DownloadProgress(this, transferredSize, transferredSize);
|
||||||
fResult.SetLength(transferredSize);
|
if (!fQuit)
|
||||||
|
fResult.SetLength(transferredSize);
|
||||||
|
|
||||||
return B_OK;
|
return fQuit ? B_INTERRUPTED : B_OK;
|
||||||
}
|
}
|
||||||
|
84
src/tests/kits/net/service/FileTest.cpp
Normal file
84
src/tests/kits/net/service/FileTest.cpp
Normal file
@ -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);
|
||||||
|
}
|
31
src/tests/kits/net/service/FileTest.h
Normal file
31
src/tests/kits/net/service/FileTest.h
Normal file
@ -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
|
@ -9,6 +9,7 @@ UnitTestLib servicekittest.so :
|
|||||||
DataTest.cpp
|
DataTest.cpp
|
||||||
HttpTest.cpp
|
HttpTest.cpp
|
||||||
UrlTest.cpp
|
UrlTest.cpp
|
||||||
|
FileTest.cpp
|
||||||
TestServer.cpp
|
TestServer.cpp
|
||||||
|
|
||||||
: be $(TARGET_NETWORK_LIBS) $(HAIKU_NETAPI_LIB) [ TargetLibstdc++ ]
|
: be $(TARGET_NETWORK_LIBS) $(HAIKU_NETAPI_LIB) [ TargetLibstdc++ ]
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "DataTest.h"
|
#include "DataTest.h"
|
||||||
#include "HttpTest.h"
|
#include "HttpTest.h"
|
||||||
#include "UrlTest.h"
|
#include "UrlTest.h"
|
||||||
|
#include "FileTest.h"
|
||||||
|
|
||||||
|
|
||||||
BTestSuite*
|
BTestSuite*
|
||||||
@ -22,6 +23,7 @@ getTestSuite()
|
|||||||
UrlTest::AddTests(*suite);
|
UrlTest::AddTests(*suite);
|
||||||
HttpTest::AddTests(*suite);
|
HttpTest::AddTests(*suite);
|
||||||
DataTest::AddTests(*suite);
|
DataTest::AddTests(*suite);
|
||||||
|
FileTest::AddTests(*suite);
|
||||||
|
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user