UPnPServer cannot handle error codes from soapRequest handlers
meisbedi opened this issue · comments
If a soap request is handled, then there is the possibility, that the result of the handler is a specific error code (e.g. invalid arguments). The current implementation does not allow, to send back such an error code to the device, that sent the soap request.
I took the following approach to fix this.
The handler for the soap request can throw an error. This error is a custom HttpStatusCode.
example: throw HttpStatusCode.custom(402, "Invalid Args")
I created a new class UPnPSoapErrorResponse, that will encapsulate the error message from the soap request handler into a soap response with the response status .internalServerError.
I took the format for this soap response from the error message of an actual UPnP renderer device.
The handling of the soap request now looks like this:
for (_, device) in self._activeDevices {
if let service = device.getService(withControlUrl: request.path) {
do {
let properties = try handler(service, soapRequest)
print("responding to soap request: \(soapRequest.actionName) with \(properties.fields.count) properties")
let soapResponse = UPnPSoapResponse(serviceType: soapRequest.serviceType,
actionName: soapRequest.actionName)
properties.fields.forEach { soapResponse[$0.key] = $0.value }
response.status = .ok
response.contentType = "text/xml"
response.data = soapResponse.xmlDocument.data(using: .utf8)
return
} catch {
print("responding to soap request: \(soapRequest.actionName) with error message")
let soapResponse = UPnPSoapErrorResponse(soapError: error as? HttpStatusCode)
response.status = .internalServerError
response.contentType = "text/xml"
response.data = soapResponse.xmlDocument.data(using: .utf8)
return
}
}
}