diff --git a/headers/os/net/HttpHeaders.h b/headers/os/net/HttpHeaders.h index d3100dde3a..0b22845b72 100644 --- a/headers/os/net/HttpHeaders.h +++ b/headers/os/net/HttpHeaders.h @@ -7,6 +7,7 @@ #include +#include #include @@ -66,6 +67,10 @@ public: bool AddHeader(const char* name, int32 value); + // Archiving + void PopulateFromArchive(BMessage*); + void Archive(BMessage*) const; + // Header deletion void Clear(); diff --git a/headers/os/net/HttpResult.h b/headers/os/net/HttpResult.h index f2a6519b05..9875f99d5b 100644 --- a/headers/os/net/HttpResult.h +++ b/headers/os/net/HttpResult.h @@ -1,5 +1,5 @@ /* - * Copyright 2010 Haiku Inc. All rights reserved. + * Copyright 2010-2017 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _B_HTTP_RESULT_H_ @@ -22,12 +22,13 @@ class BHttpResult: public BUrlResult { public: BHttpResult(const BUrl& url); + BHttpResult(BMessage*); BHttpResult(const BHttpResult& other); ~BHttpResult(); - + // Result parameters modifications void SetUrl(const BUrl& url); - + // Result parameters access const BUrl& Url() const; BString ContentType() const; @@ -37,13 +38,15 @@ public: const BHttpHeaders& Headers() const; const BString& StatusText() const; int32 StatusCode() const; - + // Result tests bool HasHeaders() const; - + // Overloaded members - BHttpResult& operator=(const BHttpResult& other); - + BHttpResult& operator=(const BHttpResult& other); + + virtual status_t Archive(BMessage*, bool) const; + static BArchivable* Instantiate(BMessage*); private: BUrl fUrl; diff --git a/headers/os/net/UrlProtocolDispatchingListener.h b/headers/os/net/UrlProtocolDispatchingListener.h index 29fa46f2c9..0107c2cfdc 100644 --- a/headers/os/net/UrlProtocolDispatchingListener.h +++ b/headers/os/net/UrlProtocolDispatchingListener.h @@ -44,7 +44,8 @@ public: virtual void HostnameResolved(BUrlRequest* caller, const char* ip); virtual void ResponseStarted(BUrlRequest* caller); - virtual void HeadersReceived(BUrlRequest* caller); + virtual void HeadersReceived(BUrlRequest* caller, + const BUrlResult& result); virtual void DataReceived(BUrlRequest* caller, const char* data, off_t position, ssize_t size); diff --git a/headers/os/net/UrlProtocolListener.h b/headers/os/net/UrlProtocolListener.h index 35c6f7cf15..bc98826240 100644 --- a/headers/os/net/UrlProtocolListener.h +++ b/headers/os/net/UrlProtocolListener.h @@ -1,5 +1,5 @@ /* - * Copyright 2010 Haiku Inc. All rights reserved. + * Copyright 2010-2017 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _B_URL_PROTOCOL_LISTENER_H_ @@ -9,6 +9,8 @@ #include #include +#include + class BCertificate; class BUrlRequest; @@ -61,7 +63,8 @@ public: Called when all the server response metadata (such as headers) have been read and parsed. */ - virtual void HeadersReceived(BUrlRequest* caller); + virtual void HeadersReceived(BUrlRequest* caller, + const BUrlResult& result); /** DataReceived(data, position, size) diff --git a/headers/os/net/UrlResult.h b/headers/os/net/UrlResult.h index c9beb00e20..a0feb35dfd 100644 --- a/headers/os/net/UrlResult.h +++ b/headers/os/net/UrlResult.h @@ -1,26 +1,33 @@ /* - * Copyright 2010 Haiku Inc. All rights reserved. + * Copyright 2010-2017 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _B_URL_RESULT_H_ #define _B_URL_RESULT_H_ +#include #include -class BUrlResult { +class BUrlResult: public BArchivable { public: + BUrlResult(); + BUrlResult(BMessage*); virtual ~BUrlResult(); + + virtual status_t Archive(BMessage*, bool) const; + void SetContentType(BString contentType); void SetLength(size_t length); virtual BString ContentType() const; virtual size_t Length() const; + static BArchivable* Instantiate(BMessage*); + private: BString fContentType; - BString fCharset; size_t fLength; }; diff --git a/headers/os/net/UrlSynchronousRequest.h b/headers/os/net/UrlSynchronousRequest.h index ae73736135..4a7dbfc3ef 100644 --- a/headers/os/net/UrlSynchronousRequest.h +++ b/headers/os/net/UrlSynchronousRequest.h @@ -24,7 +24,8 @@ public: virtual void HostnameResolved(BUrlRequest* caller, const char* ip); virtual void ResponseStarted(BUrlRequest* caller); - virtual void HeadersReceived(BUrlRequest* caller); + virtual void HeadersReceived(BUrlRequest* caller, + const BUrlResult& result); virtual void DataReceived(BUrlRequest* caller, const char* data, off_t position, ssize_t size); diff --git a/src/apps/haikudepot/server/WebAppInterface.cpp b/src/apps/haikudepot/server/WebAppInterface.cpp index 58f76b1e21..e1b2b7fbdf 100644 --- a/src/apps/haikudepot/server/WebAppInterface.cpp +++ b/src/apps/haikudepot/server/WebAppInterface.cpp @@ -210,7 +210,7 @@ public: { } - virtual void HeadersReceived(BUrlRequest* caller) + virtual void HeadersReceived(BUrlRequest* caller, const BUrlResult& result) { } diff --git a/src/kits/network/libnetapi/DataRequest.cpp b/src/kits/network/libnetapi/DataRequest.cpp index b26b94f552..627f7b957b 100644 --- a/src/kits/network/libnetapi/DataRequest.cpp +++ b/src/kits/network/libnetapi/DataRequest.cpp @@ -118,7 +118,7 @@ BDataRequest::_ProtocolLoop() fResult.SetLength(length); if (fListener != NULL) { - fListener->HeadersReceived(this); + fListener->HeadersReceived(this, fResult); fListener->DownloadProgress(this, length, length); if (length > 0) fListener->DataReceived(this, payload, 0, length); diff --git a/src/kits/network/libnetapi/FileRequest.cpp b/src/kits/network/libnetapi/FileRequest.cpp index 6c7410bedc..f8af6555b4 100644 --- a/src/kits/network/libnetapi/FileRequest.cpp +++ b/src/kits/network/libnetapi/FileRequest.cpp @@ -77,7 +77,7 @@ BFileRequest::_ProtocolLoop() return error; fResult.SetLength(size); - fListener->HeadersReceived(this); + fListener->HeadersReceived(this, fResult); ssize_t chunkSize; char chunk[4096]; @@ -113,7 +113,7 @@ BFileRequest::_ProtocolLoop() if (fListener != NULL) { fListener->ConnectionOpened(this); - fListener->HeadersReceived(this); + fListener->HeadersReceived(this, fResult); // Add a parent directory entry. fListener->DataReceived(this, "+/,\t..\r\n", transferredSize, 8); diff --git a/src/kits/network/libnetapi/GopherRequest.cpp b/src/kits/network/libnetapi/GopherRequest.cpp index 13f3a8f11d..8b4bf68555 100644 --- a/src/kits/network/libnetapi/GopherRequest.cpp +++ b/src/kits/network/libnetapi/GopherRequest.cpp @@ -325,7 +325,6 @@ BGopherRequest::_ProtocolLoop() // continue parsing the error text anyway // but it won't look good } - // now we probably have correct data dataValidated = true; @@ -334,11 +333,6 @@ BGopherRequest::_ProtocolLoop() if (fListener != NULL) fListener->ResponseStarted(this); - // we don't really have headers but well... - //! ProtocolHook:HeadersReceived - if (fListener != NULL) - fListener->HeadersReceived(this); - // now we can assign MIME type if we know it const char *mime = "application/octet-stream"; for (i = 0; gopher_type_map[i].type != GOPHER_TYPE_NONE; i++) { @@ -348,6 +342,11 @@ BGopherRequest::_ProtocolLoop() } } fResult.SetContentType(mime); + + // we don't really have headers but well... + //! ProtocolHook:HeadersReceived + if (fListener != NULL) + fListener->HeadersReceived(this, fResult); } if (_NeedsParsing()) diff --git a/src/kits/network/libnetapi/HttpHeaders.cpp b/src/kits/network/libnetapi/HttpHeaders.cpp index 352f2c1c64..fa17809992 100644 --- a/src/kits/network/libnetapi/HttpHeaders.cpp +++ b/src/kits/network/libnetapi/HttpHeaders.cpp @@ -245,6 +245,42 @@ BHttpHeaders::AddHeader(const char* name, int32 value) } +// #pragma mark Archiving + + +void +BHttpHeaders::PopulateFromArchive(BMessage* archive) +{ + Clear(); + + int32 index = 0; + char* nameFound; + for(;;) { + if (archive->GetInfo(B_STRING_TYPE, index, &nameFound, NULL) != B_OK) + return; + + BString value = archive->FindString(nameFound); + AddHeader(nameFound, value); + + index++; + } +} + + +void +BHttpHeaders::Archive(BMessage* message) const +{ + int32 count = CountHeaders(); + int32 i; + + for (i = 0; i < count; i++) + { + BHttpHeader& header = HeaderAt(i); + message->AddString(header.Name(), header.Value()); + } +} + + // #pragma mark Header deletion diff --git a/src/kits/network/libnetapi/HttpRequest.cpp b/src/kits/network/libnetapi/HttpRequest.cpp index d91654a9e6..6ee1463d7a 100644 --- a/src/kits/network/libnetapi/HttpRequest.cpp +++ b/src/kits/network/libnetapi/HttpRequest.cpp @@ -613,7 +613,7 @@ BHttpRequest::_MakeRequest() //! ProtocolHook:HeadersReceived if (fListener != NULL) - fListener->HeadersReceived(this); + fListener->HeadersReceived(this, fResult); // Parse received cookies if (fContext != NULL) { @@ -696,8 +696,6 @@ BHttpRequest::_MakeRequest() } chunkSize = strtol(chunkHeader.String(), NULL, 16); - PRINT(("BHP[%p] Chunk %s=%ld\n", this, - chunkHeader.String(), chunkSize)); if (chunkSize == 0) fRequestStatus = kRequestContentReceived; diff --git a/src/kits/network/libnetapi/HttpResult.cpp b/src/kits/network/libnetapi/HttpResult.cpp index eccca7b67b..04ee6e1c35 100644 --- a/src/kits/network/libnetapi/HttpResult.cpp +++ b/src/kits/network/libnetapi/HttpResult.cpp @@ -1,9 +1,10 @@ /* - * Copyright 2010 Haiku Inc. All rights reserved. + * Copyright 2010-2017 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Christophe Huriaux, c.huriaux@gmail.com + * Adrien Destugues, pulkomandy@pulkomandy.tk */ @@ -23,6 +24,20 @@ BHttpResult::BHttpResult(const BUrl& url) } +BHttpResult::BHttpResult(BMessage* archive) + : + BUrlResult(archive) +{ + fUrl = archive->FindString("http:url"); + fStatusCode = archive->FindInt32("http:statusCode"); + fStatusString = archive->FindString("http:statusString"); + + BMessage headers; + archive->FindMessage("http:headers", &headers); + fHeaders.PopulateFromArchive(&headers); +} + + BHttpResult::BHttpResult(const BHttpResult& other) : fUrl(other.fUrl), @@ -114,7 +129,7 @@ BHttpResult::operator=(const BHttpResult& other) { if (this == &other) return *this; - + fUrl = other.fUrl; fHeaders = other.fHeaders; fStatusCode = other.fStatusCode; @@ -122,3 +137,34 @@ BHttpResult::operator=(const BHttpResult& other) return *this; } + + +status_t +BHttpResult::Archive(BMessage* target, bool deep) const +{ + status_t result = BUrlResult::Archive(target, deep); + if (result != B_OK) + return result; + + target->AddString("http:url", fUrl); + target->AddInt32("http:statusCode", fStatusCode); + target->AddString("http:statusString", fStatusString); + + BMessage headers; + fHeaders.Archive(&headers); + target->AddMessage("http:headers", &headers); + + return B_OK; +} + + +/*static*/ BArchivable* +BHttpResult::Instantiate(BMessage* archive) +{ + if (!validate_instantiation(archive, "BHttpResult")) + { + return NULL; + } + + return new BHttpResult(archive); +} diff --git a/src/kits/network/libnetapi/UrlProtocolAsynchronousListener.cpp b/src/kits/network/libnetapi/UrlProtocolAsynchronousListener.cpp index dc53a42351..00c783277d 100644 --- a/src/kits/network/libnetapi/UrlProtocolAsynchronousListener.cpp +++ b/src/kits/network/libnetapi/UrlProtocolAsynchronousListener.cpp @@ -1,22 +1,28 @@ /* - * Copyright 2010 Haiku Inc. All rights reserved. + * Copyright 2010-2017 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Christophe Huriaux, c.huriaux@gmail.com + * Adrien Destugues, pulkomandy@pulkomandy.tk */ +#include + #include #include -#include +#include #include #include +#include + extern const char* kUrlProtocolMessageType; extern const char* kUrlProtocolCaller; + BUrlProtocolAsynchronousListener::BUrlProtocolAsynchronousListener( bool transparent) : @@ -92,7 +98,14 @@ BUrlProtocolAsynchronousListener::MessageReceived(BMessage* message) break; case B_URL_PROTOCOL_HEADERS_RECEIVED: - HeadersReceived(caller); + { + BMessage archive; + message->FindMessage("url:result", &archive); + BUrlResult* result = dynamic_cast( + instantiate_object(&archive)); + HeadersReceived(caller, *result); + delete result; + } break; case B_URL_PROTOCOL_DATA_RECEIVED: diff --git a/src/kits/network/libnetapi/UrlProtocolDispatchingListener.cpp b/src/kits/network/libnetapi/UrlProtocolDispatchingListener.cpp index ee4f184d2e..59b40901f5 100644 --- a/src/kits/network/libnetapi/UrlProtocolDispatchingListener.cpp +++ b/src/kits/network/libnetapi/UrlProtocolDispatchingListener.cpp @@ -1,14 +1,17 @@ /* - * Copyright 2010 Haiku Inc. All rights reserved. + * Copyright 2010-2017 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Christophe Huriaux, c.huriaux@gmail.com + * Adrien Destugues, pulkomandy@pulkomandy.tk */ #include + #include +#include #include @@ -27,7 +30,7 @@ BUrlProtocolDispatchingListener::BUrlProtocolDispatchingListener BUrlProtocolDispatchingListener::BUrlProtocolDispatchingListener (const BMessenger& messenger) - : + : fMessenger(messenger) { } @@ -66,9 +69,17 @@ BUrlProtocolDispatchingListener::ResponseStarted(BUrlRequest* caller) void -BUrlProtocolDispatchingListener::HeadersReceived(BUrlRequest* caller) +BUrlProtocolDispatchingListener::HeadersReceived(BUrlRequest* caller, + const BUrlResult& result) { + /* The URL request does not keep the headers valid after calling this + * method. For asynchronous delivery to work, we need to archive them + * into the message. */ BMessage message(B_URL_PROTOCOL_NOTIFICATION); + BMessage archive; + result.Archive(&archive, true); + message.AddMessage("url:result", &archive); + _SendMessage(&message, B_URL_PROTOCOL_HEADERS_RECEIVED, caller); } @@ -157,7 +168,7 @@ BUrlProtocolDispatchingListener::CertificateVerificationFailed( void -BUrlProtocolDispatchingListener::_SendMessage(BMessage* message, +BUrlProtocolDispatchingListener::_SendMessage(BMessage* message, int8 notification, BUrlRequest* caller) { ASSERT(message != NULL); diff --git a/src/kits/network/libnetapi/UrlProtocolListener.cpp b/src/kits/network/libnetapi/UrlProtocolListener.cpp index 70447d9710..3a96d94a1f 100644 --- a/src/kits/network/libnetapi/UrlProtocolListener.cpp +++ b/src/kits/network/libnetapi/UrlProtocolListener.cpp @@ -1,9 +1,10 @@ /* - * Copyright 2010 Haiku Inc. All rights reserved. + * Copyright 2010-2017 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Christophe Huriaux, c.huriaux@gmail.com + * Adrien Destugues, pulkomandy@pulkomandy.tk */ #include @@ -42,7 +43,7 @@ BUrlProtocolListener::ResponseStarted(BUrlRequest*) void -BUrlProtocolListener::HeadersReceived(BUrlRequest*) +BUrlProtocolListener::HeadersReceived(BUrlRequest*, const BUrlResult& result) { } diff --git a/src/kits/network/libnetapi/UrlResult.cpp b/src/kits/network/libnetapi/UrlResult.cpp index 67191a2da8..454c71e397 100644 --- a/src/kits/network/libnetapi/UrlResult.cpp +++ b/src/kits/network/libnetapi/UrlResult.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2013 Haiku Inc. All rights reserved. + * Copyright 2013-2017 Haiku Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -10,11 +10,44 @@ #include +BUrlResult::BUrlResult() + : + BArchivable(), + fContentType(), + fLength(0) +{ +} + + +BUrlResult::BUrlResult(BMessage* archive) + : + BArchivable(archive) +{ + fContentType = archive->FindString("ContentType"); + fLength = archive->FindInt32("Length"); +} + + BUrlResult::~BUrlResult() { } +status_t +BUrlResult::Archive(BMessage* archive, bool deep) const +{ + status_t result = BArchivable::Archive(archive, deep); + + if (result != B_OK) + return result; + + archive->AddString("ContentType", fContentType); + archive->AddInt32("Length", fLength); + + return B_OK; +} + + void BUrlResult::SetContentType(BString contentType) { @@ -41,3 +74,12 @@ BUrlResult::Length() const { return fLength; } + + +/*static*/ BArchivable* +BUrlResult::Instantiate(BMessage* archive) +{ + if (!validate_instantiation(archive, "BUrlResult")) + return NULL; + return new BUrlResult(archive); +} diff --git a/src/kits/network/libnetapi/UrlSynchronousRequest.cpp b/src/kits/network/libnetapi/UrlSynchronousRequest.cpp index 859484b993..687ee224a1 100644 --- a/src/kits/network/libnetapi/UrlSynchronousRequest.cpp +++ b/src/kits/network/libnetapi/UrlSynchronousRequest.cpp @@ -71,7 +71,7 @@ BUrlSynchronousRequest::ResponseStarted(BUrlRequest*) void -BUrlSynchronousRequest::HeadersReceived(BUrlRequest*) +BUrlSynchronousRequest::HeadersReceived(BUrlRequest*, const BUrlResult& result) { PRINT(("SynchronousRequest::HeadersReceived()\n")); }