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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
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
|
||||
HttpTest.cpp
|
||||
UrlTest.cpp
|
||||
FileTest.cpp
|
||||
TestServer.cpp
|
||||
|
||||
: be $(TARGET_NETWORK_LIBS) $(HAIKU_NETAPI_LIB) [ TargetLibstdc++ ]
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user