Subsonic API: always report the old protocol version when needed, to make DSub work again
This commit is contained in:
@@ -43,10 +43,9 @@ namespace lms::api::subsonic
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
RequestContext::RequestContext(const Wt::Http::Request& request, db::Session& dbSession, db::ObjectPtr<db::User> user, const SubsonicResourceConfig& config)
|
RequestContext::RequestContext(const Wt::Http::Request& request, db::Session& dbSession, const SubsonicResourceConfig& config)
|
||||||
: _request{ request }
|
: _request{ request }
|
||||||
, _dbSession{ dbSession }
|
, _dbSession{ dbSession }
|
||||||
, _user{ user }
|
|
||||||
, _config{ config }
|
, _config{ config }
|
||||||
, _clientName{ getMandatoryParameterAs<std::string>(_request.getParameterMap(), "c") }
|
, _clientName{ getMandatoryParameterAs<std::string>(_request.getParameterMap(), "c") }
|
||||||
, _clientProtocolVersion{ getMandatoryParameterAs<ProtocolVersion>(_request.getParameterMap(), "v") }
|
, _clientProtocolVersion{ getMandatoryParameterAs<ProtocolVersion>(_request.getParameterMap(), "v") }
|
||||||
@@ -74,6 +73,11 @@ namespace lms::api::subsonic
|
|||||||
return _dbSession;
|
return _dbSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RequestContext::setUser(const db::ObjectPtr<db::User>& user)
|
||||||
|
{
|
||||||
|
_user = user;
|
||||||
|
}
|
||||||
|
|
||||||
db::ObjectPtr<db::User> RequestContext::getUser() const
|
db::ObjectPtr<db::User> RequestContext::getUser() const
|
||||||
{
|
{
|
||||||
return _user;
|
return _user;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace lms::api::subsonic
|
|||||||
class RequestContext
|
class RequestContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RequestContext(const Wt::Http::Request& request, db::Session& dbSession, db::ObjectPtr<db::User> user, const SubsonicResourceConfig& config);
|
RequestContext(const Wt::Http::Request& request, db::Session& dbSession, const SubsonicResourceConfig& config);
|
||||||
~RequestContext();
|
~RequestContext();
|
||||||
RequestContext(const RequestContext&) = delete;
|
RequestContext(const RequestContext&) = delete;
|
||||||
RequestContext& operator=(const RequestContext&) = delete;
|
RequestContext& operator=(const RequestContext&) = delete;
|
||||||
@@ -53,6 +53,8 @@ namespace lms::api::subsonic
|
|||||||
std::istream& getBody() const;
|
std::istream& getBody() const;
|
||||||
|
|
||||||
db::Session& getDbSession();
|
db::Session& getDbSession();
|
||||||
|
|
||||||
|
void setUser(const db::ObjectPtr<db::User>& user);
|
||||||
db::ObjectPtr<db::User> getUser() const;
|
db::ObjectPtr<db::User> getUser() const;
|
||||||
|
|
||||||
std::string getClientIpAddr() const;
|
std::string getClientIpAddr() const;
|
||||||
|
|||||||
@@ -297,6 +297,8 @@ namespace lms::api::subsonic
|
|||||||
if (core::stringUtils::stringEndsWith(requestPath, ".view"))
|
if (core::stringUtils::stringEndsWith(requestPath, ".view"))
|
||||||
requestPath.resize(requestPath.length() - 5);
|
requestPath.resize(requestPath.length() - 5);
|
||||||
|
|
||||||
|
RequestContext requestContext{ request, _db.getTLSSession(), _config };
|
||||||
|
|
||||||
// First check for media retrieval endpoints
|
// First check for media retrieval endpoints
|
||||||
auto itStreamHandler{ mediaRetrievalHandlers.find(requestPath) };
|
auto itStreamHandler{ mediaRetrievalHandlers.find(requestPath) };
|
||||||
if (itStreamHandler != mediaRetrievalHandlers.end())
|
if (itStreamHandler != mediaRetrievalHandlers.end())
|
||||||
@@ -304,7 +306,7 @@ namespace lms::api::subsonic
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
LMS_SCOPED_TRACE_OVERVIEW("Subsonic", itStreamHandler->first);
|
LMS_SCOPED_TRACE_OVERVIEW("Subsonic", itStreamHandler->first);
|
||||||
handleMediaRetrievalRequest(itStreamHandler->second, request, response);
|
handleMediaRetrievalRequest(itStreamHandler->second, requestContext, request, response);
|
||||||
LMS_LOG(API_SUBSONIC, DEBUG, "Request " << requestId << " '" << requestPath << "' handled!");
|
LMS_LOG(API_SUBSONIC, DEBUG, "Request " << requestId << " '" << requestPath << "' handled!");
|
||||||
}
|
}
|
||||||
catch (const Error& e)
|
catch (const Error& e)
|
||||||
@@ -315,11 +317,7 @@ namespace lms::api::subsonic
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optional parameters
|
// Now check other endpoints
|
||||||
const ResponseFormat format{ getParameterAs<std::string>(request.getParameterMap(), "f").value_or("xml") == "json" ? ResponseFormat::json : ResponseFormat::xml };
|
|
||||||
|
|
||||||
ProtocolVersion protocolVersion{ defaultServerProtocolVersion };
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (auto itEntryPoint{ requestEntryPoints.find(requestPath) }; itEntryPoint != requestEntryPoints.end())
|
if (auto itEntryPoint{ requestEntryPoints.find(requestPath) }; itEntryPoint != requestEntryPoints.end())
|
||||||
@@ -331,11 +329,9 @@ namespace lms::api::subsonic
|
|||||||
{
|
{
|
||||||
user = getUserFromUserId(_db.getTLSSession(), authenticateUser(request));
|
user = getUserFromUserId(_db.getTLSSession(), authenticateUser(request));
|
||||||
checkUserTypeIsAllowed(user, itEntryPoint->second.allowedUserTypes);
|
checkUserTypeIsAllowed(user, itEntryPoint->second.allowedUserTypes);
|
||||||
|
requestContext.setUser(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestContext requestContext{ request, _db.getTLSSession(), user, _config };
|
|
||||||
protocolVersion = requestContext.getServerProtocolVersion();
|
|
||||||
|
|
||||||
const Response resp{ [&] {
|
const Response resp{ [&] {
|
||||||
LMS_SCOPED_TRACE_DETAILED("Subsonic", "HandleRequest");
|
LMS_SCOPED_TRACE_DETAILED("Subsonic", "HandleRequest");
|
||||||
return itEntryPoint->second.func(requestContext);
|
return itEntryPoint->second.func(requestContext);
|
||||||
@@ -344,8 +340,8 @@ namespace lms::api::subsonic
|
|||||||
{
|
{
|
||||||
LMS_SCOPED_TRACE_DETAILED("Subsonic", "WriteResponse");
|
LMS_SCOPED_TRACE_DETAILED("Subsonic", "WriteResponse");
|
||||||
|
|
||||||
resp.write(response.out(), format);
|
resp.write(response.out(), requestContext.getResponseFormat());
|
||||||
response.setMimeType(std::string{ ResponseFormatToMimeType(format) });
|
response.setMimeType(std::string{ ResponseFormatToMimeType(requestContext.getResponseFormat()) });
|
||||||
}
|
}
|
||||||
|
|
||||||
LMS_LOG(API_SUBSONIC, DEBUG, "Request " << requestId << " '" << requestPath << "' handled!");
|
LMS_LOG(API_SUBSONIC, DEBUG, "Request " << requestId << " '" << requestPath << "' handled!");
|
||||||
@@ -361,13 +357,13 @@ namespace lms::api::subsonic
|
|||||||
catch (const Error& e)
|
catch (const Error& e)
|
||||||
{
|
{
|
||||||
LMS_LOG(API_SUBSONIC, ERROR, "Error while processing request '" << requestPath << "'" << ", params = [" << parameterMapToDebugString(request.getParameterMap()) << "]" << ", code = " << static_cast<int>(e.getCode()) << ", msg = '" << e.getMessage() << "'");
|
LMS_LOG(API_SUBSONIC, ERROR, "Error while processing request '" << requestPath << "'" << ", params = [" << parameterMapToDebugString(request.getParameterMap()) << "]" << ", code = " << static_cast<int>(e.getCode()) << ", msg = '" << e.getMessage() << "'");
|
||||||
Response resp{ Response::createFailedResponse(protocolVersion, e) };
|
Response resp{ Response::createFailedResponse(requestContext.getServerProtocolVersion(), e) };
|
||||||
resp.write(response.out(), format);
|
resp.write(response.out(), requestContext.getResponseFormat());
|
||||||
response.setMimeType(std::string{ ResponseFormatToMimeType(format) });
|
response.setMimeType(std::string{ ResponseFormatToMimeType(requestContext.getResponseFormat()) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubsonicResource::handleMediaRetrievalRequest(MediaRetrievalHandlerFunc handler, const Wt::Http::Request& request, Wt::Http::Response& response)
|
void SubsonicResource::handleMediaRetrievalRequest(const MediaRetrievalHandlerFunc& handler, RequestContext& requestContext, const Wt::Http::Request& request, Wt::Http::Response& response)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -377,7 +373,7 @@ namespace lms::api::subsonic
|
|||||||
if (!request.continuation())
|
if (!request.continuation())
|
||||||
user = getUserFromUserId(_db.getTLSSession(), authenticateUser(request));
|
user = getUserFromUserId(_db.getTLSSession(), authenticateUser(request));
|
||||||
|
|
||||||
RequestContext requestContext{ request, _db.getTLSSession(), user, _config };
|
requestContext.setUser(user);
|
||||||
|
|
||||||
handler(requestContext, request, response);
|
handler(requestContext, request, response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace lms::api::subsonic
|
|||||||
void handleRequest(const Wt::Http::Request& request, Wt::Http::Response& response) override;
|
void handleRequest(const Wt::Http::Request& request, Wt::Http::Response& response) override;
|
||||||
|
|
||||||
using MediaRetrievalHandlerFunc = std::function<void(RequestContext&, const Wt::Http::Request&, Wt::Http::Response&)>;
|
using MediaRetrievalHandlerFunc = std::function<void(RequestContext&, const Wt::Http::Request&, Wt::Http::Response&)>;
|
||||||
void handleMediaRetrievalRequest(MediaRetrievalHandlerFunc handler, const Wt::Http::Request& request, Wt::Http::Response& response);
|
void handleMediaRetrievalRequest(const MediaRetrievalHandlerFunc& handler, RequestContext& requestContext, const Wt::Http::Request& request, Wt::Http::Response& response);
|
||||||
|
|
||||||
db::UserId authenticateUser(const Wt::Http::Request& request);
|
db::UserId authenticateUser(const Wt::Http::Request& request);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user