Network Kit: Prepare for HTTP range requests
* The DataReceived hook gets a position argument, making it possible for listeners to handle out-of-order data (from two range requests at different positions, for example) * Adjust HaikuDepot (only user of the API in our sources) * Add a copy constructor to HTTPRequest that copies the relevant parameters from an existing request. Makes it easy to repeat a request with a different range. Could be useful for restarting downloads, or paralellizing them. * Add SetRangeStart, SetRangeEnd calls to HTTPRequest, no implementation yet. I'm putting all the API changes in this commit as it needs to be synced with a matching haikuwebkit release. * All archs must update to HaikuWebkit 1.3.0. Previous versions are broken by this.
This commit is contained in:
parent
ba65f39ac3
commit
cfc4b62367
@ -26,6 +26,7 @@ public:
|
||||
const char *protocolName = "HTTP",
|
||||
BUrlProtocolListener* listener = NULL,
|
||||
BUrlContext* context = NULL);
|
||||
BHttpRequest(const BHttpRequest& other);
|
||||
virtual ~BHttpRequest();
|
||||
|
||||
void SetMethod(const char* const method);
|
||||
@ -38,6 +39,8 @@ public:
|
||||
void SetAutoReferrer(bool enable);
|
||||
void SetUserName(const BString& name);
|
||||
void SetPassword(const BString& password);
|
||||
void SetRangeStart(off_t position);
|
||||
void SetRangeEnd(off_t position);
|
||||
|
||||
void SetPostFields(const BHttpForm& fields);
|
||||
void SetHeaders(const BHttpHeaders& headers);
|
||||
@ -115,6 +118,8 @@ private:
|
||||
BHttpForm* fOptPostFields;
|
||||
BDataIO* fOptInputData;
|
||||
ssize_t fOptInputDataSize;
|
||||
off_t fOptRangeStart;
|
||||
off_t fOptRangeEnd;
|
||||
bool fOptSetCookies : 1;
|
||||
bool fOptFollowLocation : 1;
|
||||
bool fOptDiscardData : 1;
|
||||
|
@ -44,7 +44,8 @@ public:
|
||||
virtual void ResponseStarted(BUrlRequest* caller);
|
||||
virtual void HeadersReceived(BUrlRequest* caller);
|
||||
virtual void DataReceived(BUrlRequest* caller,
|
||||
const char* data, ssize_t size);
|
||||
const char* data, off_t position,
|
||||
ssize_t size);
|
||||
virtual void DownloadProgress(BUrlRequest* caller,
|
||||
ssize_t bytesReceived, ssize_t bytesTotal);
|
||||
virtual void UploadProgress(BUrlRequest* caller,
|
||||
|
@ -62,15 +62,17 @@ public:
|
||||
virtual void HeadersReceived(BUrlRequest* caller);
|
||||
|
||||
/**
|
||||
DataReceived(data, size)
|
||||
DataReceived(data, position, size)
|
||||
Frequency: Zero or more
|
||||
Parameters: data Pointer to the data block in memory
|
||||
position Offset of the data in the stream
|
||||
size Size of the data block
|
||||
|
||||
Called each time a full block of data is received.
|
||||
*/
|
||||
virtual void DataReceived(BUrlRequest* caller,
|
||||
const char* data, ssize_t size);
|
||||
const char* data, off_t position,
|
||||
ssize_t size);
|
||||
|
||||
/**
|
||||
DownloadProgress(bytesReceived, bytesTotal)
|
||||
|
@ -26,7 +26,8 @@ public:
|
||||
virtual void ResponseStarted(BUrlRequest* caller);
|
||||
virtual void HeadersReceived(BUrlRequest* caller);
|
||||
virtual void DataReceived(BUrlRequest* caller,
|
||||
const char* data, ssize_t size);
|
||||
const char* data, off_t position,
|
||||
ssize_t size);
|
||||
virtual void DownloadProgress(BUrlRequest* caller,
|
||||
ssize_t bytesReceived, ssize_t bytesTotal);
|
||||
virtual void UploadProgress(BUrlRequest* caller,
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void DataReceived(BUrlRequest* caller, const char* data,
|
||||
ssize_t size)
|
||||
off_t position, ssize_t size)
|
||||
{
|
||||
// printf("DataReceived(%p): %ld bytes\n", caller, size);
|
||||
|
||||
|
@ -105,7 +105,7 @@ BDataRequest::_ProtocolLoop()
|
||||
if (fListener != NULL) {
|
||||
fListener->DownloadProgress(this, length, length);
|
||||
if (length > 0)
|
||||
fListener->DataReceived(this, payload, length);
|
||||
fListener->DataReceived(this, payload, 0, length);
|
||||
}
|
||||
|
||||
if (isBase64)
|
||||
|
@ -77,7 +77,7 @@ BFileRequest::_ProtocolLoop()
|
||||
ssize_t chunkSize;
|
||||
char chunk[4096];
|
||||
while ((chunkSize = file.Read(chunk, sizeof(chunk))) > 0) {
|
||||
fListener->DataReceived(this, chunk, chunkSize);
|
||||
fListener->DataReceived(this, chunk, transferredSize, chunkSize);
|
||||
transferredSize += chunkSize;
|
||||
}
|
||||
// Return error if we didn't transfer everything
|
||||
@ -110,10 +110,10 @@ BFileRequest::_ProtocolLoop()
|
||||
fListener->ConnectionOpened(this);
|
||||
|
||||
// Add a parent directory entry.
|
||||
fListener->DataReceived(this, "+/,\t..\r\n",8);
|
||||
fListener->DataReceived(this, "+/,\t..\r\n", transferredSize, 8);
|
||||
transferredSize += 8;
|
||||
}
|
||||
|
||||
int size = 0;
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
BEntry entry;
|
||||
while (directory.GetNextEntry(&entry) != B_ENTRY_NOT_FOUND) {
|
||||
@ -137,14 +137,16 @@ BFileRequest::_ProtocolLoop()
|
||||
|
||||
entry.GetName(name);
|
||||
epfl << "\t" << name << "\r\n";
|
||||
if (fListener != NULL)
|
||||
fListener->DataReceived(this, epfl.String(), epfl.Length());
|
||||
size += epfl.Length();
|
||||
if (fListener != NULL) {
|
||||
fListener->DataReceived(this, epfl.String(), transferredSize,
|
||||
epfl.Length());
|
||||
}
|
||||
transferredSize += epfl.Length();
|
||||
}
|
||||
|
||||
if (fListener != NULL)
|
||||
fListener->DownloadProgress(this, size, size);
|
||||
fResult.SetLength(size);
|
||||
fListener->DownloadProgress(this, transferredSize, transferredSize);
|
||||
fResult.SetLength(transferredSize);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -43,10 +43,39 @@ BHttpRequest::BHttpRequest(const BUrl& url, bool ssl, const char* protocolName,
|
||||
fOptPostFields(NULL),
|
||||
fOptInputData(NULL),
|
||||
fOptInputDataSize(-1),
|
||||
fOptRangeStart(-1),
|
||||
fOptRangeEnd(-1),
|
||||
fOptFollowLocation(true)
|
||||
{
|
||||
_ResetOptions();
|
||||
if (ssl)
|
||||
if (fSSL)
|
||||
fSocket = new(std::nothrow) BSecureSocket();
|
||||
else
|
||||
fSocket = new(std::nothrow) BSocket();
|
||||
}
|
||||
|
||||
|
||||
BHttpRequest::BHttpRequest(const BHttpRequest& other)
|
||||
:
|
||||
BUrlRequest(other.Url(), other.fListener, other.fContext,
|
||||
"BUrlProtocol.HTTP", other.fSSL ? "HTTPS" : "HTTP"),
|
||||
fSocket(NULL),
|
||||
fSSL(other.fSSL),
|
||||
fRequestMethod(other.fRequestMethod),
|
||||
fHttpVersion(other.fHttpVersion),
|
||||
fResult(other.fUrl),
|
||||
fRequestStatus(kRequestInitialState),
|
||||
fOptHeaders(NULL),
|
||||
fOptPostFields(NULL),
|
||||
fOptInputData(NULL),
|
||||
fOptInputDataSize(NULL),
|
||||
fOptRangeStart(other.fOptRangeStart),
|
||||
fOptRangeEnd(other.fOptRangeEnd),
|
||||
fOptFollowLocation(other.fOptFollowLocation)
|
||||
{
|
||||
_ResetOptions();
|
||||
// FIXME some options may be copied from other instead.
|
||||
if (fSSL)
|
||||
fSocket = new(std::nothrow) BSecureSocket();
|
||||
else
|
||||
fSocket = new(std::nothrow) BSocket();
|
||||
@ -552,6 +581,7 @@ BHttpRequest::_MakeRequest()
|
||||
ssize_t bytesRead = 0;
|
||||
ssize_t bytesReceived = 0;
|
||||
ssize_t bytesTotal = 0;
|
||||
off_t bytesUnpacked = 0;
|
||||
char* inputTempBuffer = new(std::nothrow) char[kHttpBufferSize];
|
||||
ssize_t inputTempSize = kHttpBufferSize;
|
||||
ssize_t chunkSize = -1;
|
||||
@ -705,11 +735,13 @@ BHttpRequest::_MakeRequest()
|
||||
BStackOrHeapArray<char, 4096> buffer(size);
|
||||
size = decompressorStorage.Read(buffer, size);
|
||||
if (size > 0) {
|
||||
fListener->DataReceived(this, buffer, size);
|
||||
fListener->DataReceived(this, buffer, bytesUnpacked,
|
||||
size);
|
||||
bytesUnpacked += size;
|
||||
}
|
||||
} else {
|
||||
fListener->DataReceived(this, inputTempBuffer,
|
||||
bytesRead);
|
||||
bytesReceived - bytesRead, bytesRead);
|
||||
}
|
||||
fListener->DownloadProgress(this, bytesReceived,
|
||||
bytesTotal);
|
||||
@ -724,7 +756,9 @@ BHttpRequest::_MakeRequest()
|
||||
BStackOrHeapArray<char, 4096> buffer(size);
|
||||
size = decompressorStorage.Read(buffer, size);
|
||||
if (fListener != NULL && size > 0) {
|
||||
fListener->DataReceived(this, buffer, size);
|
||||
fListener->DataReceived(this, buffer,
|
||||
bytesUnpacked, size);
|
||||
bytesUnpacked += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +106,9 @@ BUrlProtocolAsynchronousListener::MessageReceived(BMessage* message)
|
||||
return;
|
||||
}
|
||||
|
||||
DataReceived(caller, data, size);
|
||||
off_t position = message->FindInt32("url:position");
|
||||
|
||||
DataReceived(caller, data, position, size);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -75,12 +75,15 @@ BUrlProtocolDispatchingListener::HeadersReceived(BUrlRequest* caller)
|
||||
|
||||
void
|
||||
BUrlProtocolDispatchingListener::DataReceived(BUrlRequest* caller,
|
||||
const char* data, ssize_t size)
|
||||
const char* data, off_t position, ssize_t size)
|
||||
{
|
||||
BMessage message(B_URL_PROTOCOL_NOTIFICATION);
|
||||
status_t result = message.AddData("url:data", B_STRING_TYPE, data, size,
|
||||
true, 1);
|
||||
assert(result == B_OK);
|
||||
|
||||
result = message.AddInt32("url:position", position);
|
||||
assert(result == B_OK);
|
||||
|
||||
_SendMessage(&message, B_URL_PROTOCOL_DATA_RECEIVED, caller);
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ BUrlProtocolListener::HeadersReceived(BUrlRequest*)
|
||||
|
||||
|
||||
void
|
||||
BUrlProtocolListener::DataReceived(BUrlRequest*, const char*, ssize_t)
|
||||
BUrlProtocolListener::DataReceived(BUrlRequest*, const char*, off_t, ssize_t)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ BUrlSynchronousRequest::HeadersReceived(BUrlRequest*)
|
||||
|
||||
void
|
||||
BUrlSynchronousRequest::DataReceived(BUrlRequest*, const char*,
|
||||
ssize_t size)
|
||||
off_t, ssize_t size)
|
||||
{
|
||||
PRINT(("SynchronousRequest::DataReceived(%zd)\n", size));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user