bjtj / swift-upnp-tools

Swift UPnP Tool

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.

UPnPSoapErrorResponse.txt

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
                }
            }
        }