Compare commits

...
Author SHA1 Message Date
Automatic Release Builder 7a773f30e6 new version: 2018.3.5 2020-04-02 08:37:31 +01:00
James Turner eb03782908 Packages: randomised mirror URL selection 2020-03-22 09:22:31 +00:00
Mykola Orliuk c79580d853 BoostTestTargets.cmake: support CMake 3.15
Signed-off-by: James Turner <zakalawe@mac.com>
2019-10-17 09:47:48 +01:00
James Turner 1b3c048363 New version : 2018.3.4 2019-08-07 09:58:45 +01:00
Dan Wickstrom 01f689a0e4 Aircraft model reinit deletes sound effect samples, but leaves them defined in the sample group, so a reload doesn't re-add them. 2019-07-30 16:36:49 +01:00
Scott Giese b155f2e40f [soundmgr_openal] Pause/Resume Sound.
The following changes fixes a case for me where I hear the sound change levels up and down for each pause un-pause cycle.
Patch provided by daniel.c.wickstrom@gmail.com.
2019-07-30 16:36:49 +01:00
Tim Moore 10ab8b830a nasal/lib.c: Make copy of va_list for each traversal
It's not portable to traverse a va_list more than once.
2019-07-30 16:36:49 +01:00
James Turner 8a4871db83 Improve HTTP redirect handling, and add test.
Ensure we get the final status code for the request after redirecting.
2019-07-30 16:36:49 +01:00
12 changed files with 123 additions and 35 deletions
+3
View File
@@ -10,6 +10,9 @@ if(COMMAND cmake_policy)
if(POLICY CMP0067)
cmake_policy(SET CMP0067 NEW)
endif()
if(POLICY CMP0093)
cmake_policy(SET CMP0093 NEW)
endif()
endif()
+11 -5
View File
@@ -46,11 +46,17 @@ set(BOOST_TEST_TARGET_PREFIX "test")
if(NOT Boost_FOUND)
find_package(Boost 1.34.0 QUIET)
endif()
if("${Boost_VERSION}0" LESS "1034000")
if (NOT Boost_VERSION_MACRO)
# Compatibility with pre CMP0093 (CMake 3.15)
set(Boost_VERSION_MACRO ${Boost_VERSION})
endif()
if("${Boost_VERSION_MACRO}0" LESS "1034000")
set(_shared_msg
"NOTE: boost::test-based targets and tests cannot "
"be added: boost >= 1.34.0 required but not found. "
"(found: '${Boost_VERSION}'; want >=103400) ")
"(found: '${Boost_VERSION_MACRO}'; want >=103400) ")
if(ENABLE_TESTS)
message(FATAL_ERROR
${_shared_msg}
@@ -66,7 +72,7 @@ endif()
include(GetForceIncludeDefinitions)
include(CopyResourcesToBuildTree)
if(Boost_FOUND AND NOT "${Boost_VERSION}0" LESS "1034000")
if(Boost_FOUND AND NOT "${Boost_VERSION_MACRO}0" LESS "1034000")
set(_boosttesttargets_libs)
set(_boostConfig "BoostTestTargetsIncluded.h")
if(NOT Boost_UNIT_TEST_FRAMEWORK_LIBRARY)
@@ -129,7 +135,7 @@ function(add_boost_test _name)
"Syntax error in use of add_boost_test: at least one source file required!")
endif()
if(Boost_FOUND AND NOT "${Boost_VERSION}0" LESS "1034000")
if(Boost_FOUND AND NOT "${Boost_VERSION_MACRO}0" LESS "1034000")
include_directories(${Boost_INCLUDE_DIRS})
@@ -221,7 +227,7 @@ function(add_boost_test _name)
set(_test_command ${_target_name})
endif()
if(TESTS AND ( "${Boost_VERSION}" VERSION_GREATER "103799" ))
if(TESTS AND ( "${Boost_VERSION_MACRO}" VERSION_GREATER "103799" ))
foreach(_test ${TESTS})
add_test(
${_name}-${_test}
+14
View File
@@ -472,12 +472,26 @@ size_t Client::requestReadCallback(char *ptr, size_t size, size_t nmemb, void *u
return actualBytes;
}
bool isRedirectStatus(int code)
{
return ((code >= 300) && (code < 400));
}
size_t Client::requestHeaderCallback(char *rawBuffer, size_t size, size_t nitems, void *userdata)
{
size_t byteSize = size * nitems;
Request* req = static_cast<Request*>(userdata);
std::string h = strutils::simplify(std::string(rawBuffer, byteSize));
if (req->readyState() >= HTTP::Request::HEADERS_RECEIVED) {
// this can happen with chunked transfers (secondary chunks)
// or redirects
if (isRedirectStatus(req->responseCode())) {
req->responseStart(h);
return byteSize;
}
}
if (req->readyState() == HTTP::Request::OPENED) {
req->responseStart(h);
return byteSize;
+10
View File
@@ -328,6 +328,16 @@ unsigned int Request::responseLength() const
return _responseLength;
}
//------------------------------------------------------------------------------
void Request::setSuccess(int code)
{
_responseStatus = code;
_responseReason.clear();
if( !isComplete() ) {
setReadyState(DONE);
}
}
//------------------------------------------------------------------------------
void Request::setFailure(int code, const std::string& reason)
{
+1 -1
View File
@@ -224,7 +224,7 @@ protected:
virtual void onAlways();
void setFailure(int code, const std::string& reason);
void setSuccess(int code);
private:
friend class Client;
friend class Connection;
+35 -1
View File
@@ -273,7 +273,23 @@ public:
d << "\r\n"; // final CRLF to terminate the headers
d << contentStr;
push(d.str().c_str());
} else if (path == "/test_redirect") {
string contentStr("<html>See <a href=\"wibble\">Here</a></html>");
stringstream d;
d << "HTTP/1.1 " << 302 << " " << "Found" << "\r\n";
d << "Location:" << " http://localhost:2000/was_redirected" << "\r\n";
d << "Content-Length:" << contentStr.size() << "\r\n";
d << "\r\n"; // final CRLF to terminate the headers
d << contentStr;
push(d.str().c_str());
} else if (path == "/was_redirected") {
string contentStr(BODY1);
stringstream d;
d << "HTTP/1.1 " << 200 << " " << reasonForCode(200) << "\r\n";
d << "Content-Length:" << contentStr.size() << "\r\n";
d << "\r\n"; // final CRLF to terminate the headers
d << contentStr;
push(d.str().c_str());
} else {
TestServerChannel::processRequestHeaders();
}
@@ -773,6 +789,24 @@ cout << "testing proxy close" << endl;
SG_CHECK_EQUAL(tr2->bodyData, string(BODY1));
SG_CHECK_EQUAL(tr2->responseBytesReceived(), strlen(BODY1));
}
{
cout << "redirect test" << endl;
// redirect test
testServer.disconnectAll();
cl.clearAllConnections();
TestRequest* tr = new TestRequest("http://localhost:2000/test_redirect");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
waitForComplete(&cl, tr);
SG_CHECK_EQUAL(tr->responseCode(), 200);
SG_CHECK_EQUAL(tr->responseReason(), string("OK"));
SG_CHECK_EQUAL(tr->responseLength(), strlen(BODY1));
SG_CHECK_EQUAL(tr->responseBytesReceived(), strlen(BODY1));
SG_CHECK_EQUAL(tr->bodyData, string(BODY1));
}
cout << "all tests passed ok" << endl;
return EXIT_SUCCESS;
+2 -4
View File
@@ -30,7 +30,6 @@ public:
virtual ~TestServerChannel()
{
std::cerr << "dtor test server channel" << std::endl;
}
virtual void collectIncomingData(const char* s, int n)
@@ -139,8 +138,8 @@ public:
void sendErrorResponse(int code, bool close, std::string content)
{
std::cerr << "sending error " << code << " for " << path << std::endl;
std::cerr << "\tcontent:" << content << std::endl;
// std::cerr << "sending error " << code << " for " << path << std::endl;
// std::cerr << "\tcontent:" << content << std::endl;
std::stringstream headerData;
headerData << "HTTP/1.1 " << code << " " << reasonForCode(code) << "\r\n";
@@ -168,7 +167,6 @@ public:
virtual void handleClose (void)
{
std::cerr << "channel close" << std::endl;
NetBufferChannel::handleClose();
}
+6 -3
View File
@@ -302,15 +302,18 @@ static char* dosprintf(char* f, ...)
char* buf;
va_list va;
int olen, len = 16;
va_start(va, f);
while(1) {
buf = naAlloc(len);
va_start(va, f);
olen = vsnprintf(buf, len, f, va);
va_list vaCopy;
va_copy(vaCopy, va);
olen = vsnprintf(buf, len, f, vaCopy);
if(olen >= 0 && olen < len) {
va_end(va);
va_end(vaCopy);
return buf;
}
va_end(va);
va_end(vaCopy);
naFree(buf);
len *= 2;
}
+36 -19
View File
@@ -18,8 +18,8 @@
#include <simgear_config.h>
#include <simgear/package/Install.hxx>
#include <boost/foreach.hpp>
#include <fstream>
#include <cstdlib>
#include <simgear/package/unzip.h>
#include <simgear/package/md5.h>
@@ -43,21 +43,17 @@ namespace pkg {
class Install::PackageArchiveDownloader : public HTTP::Request
{
public:
PackageArchiveDownloader(InstallRef aOwner) :
PackageArchiveDownloader(InstallRef aOwner, const string_list& urls) :
HTTP::Request("" /* dummy URL */),
m_owner(aOwner)
{
m_urls = m_owner->package()->downloadUrls();
if (m_urls.empty()) {
throw sg_exception("no package download URLs");
m_urls = urls;
if (urls.empty()) {
m_urls = m_owner->package()->downloadUrls();
}
// if (m_owner->package()->properties()->hasChild("archive-type")) {
// setArchiveTypeFromExtension(m_owner->package()->properties()->getStringValue("archive-type"));
//}
selectMirrorUrl();
// TODO randomise order of m_urls
m_extractPath = aOwner->path().dir();
m_extractPath.append("_extract_" + aOwner->package()->md5());
@@ -93,12 +89,19 @@ public:
return (m_downloaded * 100) / responseLength();
}
protected:
virtual std::string url() const
void selectMirrorUrl()
{
return m_urls.front();
const int randomizedIndex = rand() % m_urls.size();
m_activeURL = m_urls.at(randomizedIndex);
m_urls.erase(m_urls.begin() + randomizedIndex);
}
virtual std::string url() const override
{
return m_activeURL;
}
virtual void responseHeadersComplete()
void responseHeadersComplete() override
{
Request::responseHeadersComplete();
@@ -110,7 +113,7 @@ protected:
SG_MD5Init(&m_md5);
}
virtual void gotBodyData(const char* s, int n)
void gotBodyData(const char* s, int n) override
{
const uint8_t* ubytes = (uint8_t*) s;
SG_MD5Update(&m_md5, ubytes, n);
@@ -119,10 +122,10 @@ protected:
m_extractor->extractBytes(ubytes, n);
}
virtual void onDone()
void onDone() override
{
if (responseCode() != 200) {
SG_LOG(SG_GENERAL, SG_ALERT, "download failure:" << responseCode() <<
SG_LOG(SG_GENERAL, SG_WARN, "download failure:" << responseCode() <<
"\n\t" << url());
Delegate::StatusCode code = Delegate::FAIL_DOWNLOAD;
if (responseCode() == 404) {
@@ -139,7 +142,7 @@ protected:
strutils::encodeHex(digest, MD5_DIGEST_LENGTH);
if (hex_md5 != m_owner->package()->md5()) {
SG_LOG(SG_GENERAL, SG_ALERT, "md5 verification failed:\n"
SG_LOG(SG_GENERAL, SG_WARN, "md5 verification failed:\n"
<< "\t" << hex_md5 << "\n\t"
<< m_owner->package()->md5() << "\n\t"
<< "downloading from:" << url());
@@ -194,7 +197,7 @@ protected:
m_owner->installResult(Delegate::STATUS_SUCCESS);
}
virtual void onFail()
void onFail() override
{
if (responseCode() == -1) {
doFailure(Delegate::USER_CANCELLED);
@@ -210,6 +213,18 @@ private:
if (dir.exists()) {
dir.remove(true /* recursive */);
}
const auto canRetry = (aReason == Delegate::FAIL_NOT_FOUND) || (aReason == Delegate::FAIL_DOWNLOAD);
if (canRetry && !m_urls.empty()) {
SG_LOG(SG_GENERAL, SG_WARN, "archive download failed from:" << m_activeURL
<< "\n\twill retry with next mirror");
// becuase selectMirrorUrl erased the active URL from m_urls,
// this new request will select one of the other mirrors
auto retryDownload = new PackageArchiveDownloader(m_owner, m_urls);
m_owner->m_download.reset(retryDownload);
m_owner->package()->catalog()->root()->makeHTTPRequest(retryDownload);
return;
}
// TODO - try other mirrors
m_owner->m_download.reset(); // ensure we get cleaned up
@@ -218,6 +233,7 @@ private:
InstallRef m_owner;
string m_activeURL;
string_list m_urls;
SG_MD5_CTX m_md5;
SGPath m_extractPath;
@@ -281,7 +297,7 @@ void Install::startUpdate()
return; // already active
}
m_download = new PackageArchiveDownloader(this);
m_download = new PackageArchiveDownloader(this, {});
m_package->catalog()->root()->makeHTTPRequest(m_download);
m_package->catalog()->root()->startInstall(this);
}
@@ -341,6 +357,7 @@ void Install::cancelDownload()
}
m_package->catalog()->root()->cancelDownload(this);
m_download.clear();
}
SGPath Install::primarySetPath() const
+1 -1
View File
@@ -340,7 +340,7 @@ void SGSoundMgr::suspend()
for ( auto current = d->_sample_groups.begin();
current != d->_sample_groups.end(); ++current ) {
SGSampleGroup *sgrp = current->second;
sgrp->stop();
sgrp->suspend();
}
_active = false;
}
+3
View File
@@ -83,6 +83,9 @@ SGXmlSound::~SGXmlSound()
if (_sample)
_sample->stop();
if (_sgrp && (_name != ""))
_sgrp->remove(_name);
_volume.clear();
_pitch.clear();
}
+1 -1
View File
@@ -1 +1 @@
2018.3.3
2018.3.5