From a69c0ee759d679f9051aaa56aa959c77630bd00f Mon Sep 17 00:00:00 2001 From: Fishpond Date: Sat, 29 Apr 2017 07:24:52 +0200 Subject: [PATCH] Allow 3 redirects in stream Urls, ignore html redirect message in HttpUtils::GetAll --- HttpUtils.cpp | 20 +++++++++++++++----- Makefile | 2 +- README.md | 2 ++ StreamIO.cpp | 42 ++++++++++++++++++++++++++++++++---------- StreamIO.h | 2 ++ 5 files changed, 52 insertions(+), 16 deletions(-) diff --git a/HttpUtils.cpp b/HttpUtils.cpp index c0e6749..1abf9d3 100644 --- a/HttpUtils.cpp +++ b/HttpUtils.cpp @@ -9,24 +9,32 @@ class HttpIOReader : public BUrlProtocolListener { public: - HttpIOReader(BPositionIO* data, BHttpHeaders* responseHeaders, size_t limit) { - fData = data; - fLimit = limit; - fHeaders = responseHeaders; + HttpIOReader(BPositionIO* data, BHttpHeaders* responseHeaders, size_t limit) + : fData(data), + fLimit(limit), + fHeaders(responseHeaders), + fIsRedirect(false) + { } + ~HttpIOReader() { } + virtual void HeadersReceived(BUrlRequest* caller, const BUrlResult& result) { const BHttpResult* httpResult = dynamic_cast(&result); if (httpResult && fHeaders) { *fHeaders = httpResult->Headers(); + fIsRedirect = BHttpRequest::IsRedirectionStatusCode(httpResult->StatusCode()); } } virtual void DataReceived(BUrlRequest* caller, const char* data, off_t position, ssize_t size) { + if (fIsRedirect) + return; + if (fData == NULL) { caller->Stop(); return; } - + fData->Write(data, size); if (fLimit) { if (fLimit < size) @@ -38,6 +46,8 @@ class HttpIOReader : public BUrlProtocolListener { private: BPositionIO* fData; BHttpHeaders* fHeaders; + bool fIsRedirect; + size_t fLimit; }; diff --git a/Makefile b/Makefile index 7caa120..b86bcd1 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ V_MAJOR = 0 V_MIDDLE = 0 V_MINOR = 3 V_VARIETY = B_APPV_DEVELOPMENT -V_BUILD = 10 +V_BUILD = 11 TARGET_DIR := ./dist PACKAGE = $(TARGET_DIR)/$(NAME)_$(VERSION)-$(ARCH).hpkg diff --git a/README.md b/README.md index 0fcd641..c51b70e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # Haiku-Radio Haiku native application to search for an listen to internet radio stations. + +Will build binary and package on all Haiku architectures. diff --git a/StreamIO.cpp b/StreamIO.cpp index 9a91530..afdb952 100644 --- a/StreamIO.cpp +++ b/StreamIO.cpp @@ -43,7 +43,8 @@ StreamIO::StreamIO(Station* station, BLooper* MetaListener) fUntilMetaEnd(0), fMetaListener(MetaListener), fFrameSync(none), - fLimit(0) + fLimit(0), + fBuffered(0) { fReq = dynamic_cast(BUrlProtocolRoster::MakeRequest(station->StreamUrl(), this)); @@ -53,7 +54,7 @@ StreamIO::StreamIO(Station* station, BLooper* MetaListener) headers->AddHeader("Accept", "audio/*"); fReq->AdoptHeaders(headers); fReq->SetFollowLocation(true); - fReq->SetMaxRedirections(2); + fReq->SetMaxRedirections(3); fInputAdapter = BuildInputAdapter(); if (*station->Mime() == "audio/mpeg" || *station->Mime() == "audio/aacp") @@ -85,13 +86,22 @@ ssize_t StreamIO::ReadAt(off_t position, void* buffer, size_t size) { if (fLimit == 0 || position < fLimit) { ssize_t read = BAdapterIO::ReadAt(position, buffer, size); - if (read > 0) - TRACE("Read %ld of %ld bytes from position %ld\n", read, size, position); - else - TRACE("Readin %ld bytes from position %ld failed - %s\n", size, position, strerror(read)); + if (read > 0) { + TRACE("Read %" B_PRIdSSIZE " of %" B_PRIuSIZE + " bytes from position %" B_PRIdOFF + ", %" B_PRIuSIZE " remaining\n", + read, size, position, Buffered()); + fBuffered -= read; + } else + TRACE("Reading %" B_PRIuSIZE " bytes from position %" B_PRIdOFF + " failed - %s\n", + size, position, strerror(read)); + return read; } else { - TRACE("Position %ld has reached limit of %ld, blocking...\n", position, fLimit); + TRACE("Position %" B_PRIuSIZE " has reached limit of %" B_PRIuSIZE + ", blocking...\n", + position, fLimit); return 0; } } @@ -101,6 +111,11 @@ StreamIO::SetSize(off_t size) { return B_NOT_SUPPORTED; } +size_t +StreamIO::Buffered() { + return fBuffered; +} + void StreamIO::SetLimiter(size_t limit) { fLimit = limit; @@ -141,7 +156,11 @@ StreamIO::HeadersReceived(BUrlRequest* request, const BUrlResult& result) { if (httpResult->Length() > 0) { fDataFuncs.Add(&StreamIO::DataRedirectReceived, 0); } - TRACE("Redirected to %s\n", httpResult->Headers()["location"]); + if (httpResult->StatusCode() == 301) { // Permanent redirect + fStation->SetStreamUrl(httpResult->Headers()["location"]); + TRACE("Permanently redirected to %s\n", httpResult->Headers()["location"]); + } else + TRACE("Redirected to %s\n", httpResult->Headers()["location"]); return; } @@ -165,6 +184,7 @@ StreamIO::HeadersReceived(BUrlRequest* request, const BUrlResult& result) { void StreamIO::DataSyncedReceived(BUrlRequest* request, const char* data, off_t position, ssize_t size, int next) { fInputAdapter->Write(data, size); + fBuffered += size; } void @@ -217,7 +237,7 @@ StreamIO::DataWithMetaReceived(BUrlRequest* request, const char* data, off_t pos } else if (fUntilMetaEnd > 512) { fUntilMetaStart = fMetaInt; fUntilMetaEnd = 0; - TRACE("Meta: Size of %ld too large\n"); + TRACE("Meta: Size of " B_PRIdOFF " too large\n"); data--; position--; size++; @@ -254,7 +274,9 @@ StreamIO::DataUnsyncedReceived(BUrlRequest* request, const char* data, off_t pos fFrameSync = none; } if (position + frameStart > 8192) { - MSG("No mp3 frame header encountered in first %ld bytes, giving up...", position + frameStart); + MSG("No mp3 frame header encountered in first %" B_PRIuSIZE + " bytes, giving up...", + position + frameStart); next--; fDataFuncs.Remove(next); DataFunc nextFunc = fDataFuncs.Item(next); diff --git a/StreamIO.h b/StreamIO.h index 2056ec1..990b82b 100644 --- a/StreamIO.h +++ b/StreamIO.h @@ -93,6 +93,7 @@ class StreamIO : public BAdapterIO, protected BUrlProtocolListener { virtual status_t Open(); virtual bool IsRunning() const; void SetLimiter(size_t limit = 0); + size_t Buffered(); protected: virtual status_t SeekRequested(off_t position); virtual void HeadersReceived(BUrlRequest* request, @@ -144,6 +145,7 @@ class StreamIO : public BAdapterIO, protected BUrlProtocolListener { }; FrameSync fFrameSync; size_t fLimit; + size_t fBuffered; }; #endif /* STREAMIO_H */