Previously, BUrlRequest returns data received via a callback that can't return any value. This approach have several issues: - It's not possible to signify failures to the request. - Users have to implement custom listeners just to handle the common case of outputting to a buffer/file/etc. - The received data has to be serialized into BMessage when BUrlProtocolDispatchingListener is employed. This can cause a noticible slowdown in real-world scenarios as evident by #10748. With this change, BUrlRequest will output directly into a BDataIO, which exposes a richer API for request handlers to work with (for example a BitTorrent client can request a BPositionIO for non-linear data delivery), as well as simplifying common cases for users. The adaptation only requires one additional API: BHttpRequest::SetStopOnError(). This API simply instructs the HTTP request handler to cancel the request if an HTTP error is occurred. Change-Id: I4160884d77bff0e7678e0a623e2587987704443a Reviewed-on: https://review.haiku-os.org/c/haiku/+/3084 Reviewed-by: Adrien Destugues <[email protected]>
102 lines
1.9 KiB
C++
102 lines
1.9 KiB
C++
/*
|
|
* 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"
|
|
|
|
|
|
using namespace BPrivate::Network;
|
|
|
|
|
|
class StopTestListener : public BDataIO {
|
|
public:
|
|
StopTestListener(BUrlRequest* request = NULL)
|
|
{
|
|
SetRequest(request);
|
|
}
|
|
|
|
ssize_t Write(const void*, size_t size)
|
|
{
|
|
fRequest->Stop();
|
|
return size;
|
|
}
|
|
|
|
void SetRequest(BUrlRequest* request)
|
|
{
|
|
fRequest = request;
|
|
}
|
|
|
|
private:
|
|
BUrlRequest* fRequest;
|
|
};
|
|
|
|
|
|
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);
|
|
|
|
listener.SetRequest(request);
|
|
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);
|
|
|
|
listener.SetRequest(request);
|
|
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);
|
|
}
|