private IResponse ProcessSoapRequest(IRequest request) { var soap = new XmlDocument(); soap.LoadXml(request.Body); var sparams = new RawHeaders(); var body = soap.SelectSingleNode("//soap:Body", namespaceMgr); if (body == null) { throw new HttpStatusException(HttpCode.InternalError); } var method = body.FirstChild; foreach (var p in method.ChildNodes) { var e = p as XmlElement; if (e == null) { continue; } sparams.Add(e.LocalName, e.InnerText.Trim()); } var env = new XmlDocument(); env.AppendChild(env.CreateXmlDeclaration("1.0", "utf-8", "yes")); var envelope = env.CreateElement("SOAP-ENV", "Envelope", NS_SOAPENV); env.AppendChild(envelope); envelope.SetAttribute( "encodingStyle", NS_SOAPENV, "http://schemas.xmlsoap.org/soap/encoding/"); var rbody = env.CreateElement("SOAP-ENV:Body", NS_SOAPENV); env.DocumentElement?.AppendChild(rbody); var code = HttpCode.Ok; try { IEnumerable<KeyValuePair<string, string>> result; switch (method.LocalName) { case "GetSearchCapabilities": result = HandleGetSearchCapabilities(); break; case "GetSortCapabilities": result = HandleGetSortCapabilities(); break; case "GetSystemUpdateID": result = HandleGetSystemUpdateID(); break; case "Browse": result = HandleBrowse(request, sparams); break; case "X_GetFeatureList": result = HandleXGetFeatureList(); break; case "X_SetBookmark": result = HandleXSetBookmark(sparams); break; case "GetCurrentConnectionIDs": result = HandleGetCurrentConnectionIDs(); break; case "GetCurrentConnectionInfo": result = HandleGetCurrentConnectionInfo(); break; case "GetProtocolInfo": result = HandleGetProtocolInfo(); break; case "IsAuthorized": result = HandleIsAuthorized(); break; case "IsValidated": result = HandleIsValidated(); break; case "RegisterDevice": result = HandleRegisterDevice(); break; default: throw new HttpStatusException(HttpCode.NotFound); } var response = env.CreateElement($"u:{method.LocalName}Response", method.NamespaceURI); rbody.AppendChild(response); foreach (var i in result) { var ri = env.CreateElement(i.Key); ri.InnerText = i.Value; response.AppendChild(ri); } } catch (Exception ex) { code = HttpCode.InternalError; var fault = env.CreateElement("SOAP-ENV", "Fault", NS_SOAPENV); var faultCode = env.CreateElement("faultcode"); faultCode.InnerText = "500"; fault.AppendChild(faultCode); var faultString = env.CreateElement("faultstring"); faultString.InnerText = ex.ToString(); fault.AppendChild(faultString); var detail = env.CreateDocumentFragment(); detail.InnerXml = "<detail><UPnPError xmlns=\"urn:schemas-upnp-org:control-1-0\"><errorCode>401</errorCode><errorDescription>Invalid Action</errorDescription></UPnPError></detail>"; fault.AppendChild(detail); rbody.AppendChild(fault); WarnFormat( "Invalid call: Action: {0}, Params: {1}, Problem {2}", method.LocalName, sparams, ex.Message); } var rv = new StringResponse(code, "text/xml", env.OuterXml); rv.Headers.Add("EXT", string.Empty); return rv; }
private IResponse ProcessSoapRequest(IRequest request) { var soap = new XmlDocument(); soap.LoadXml(request.Body); var sparams = new RawHeaders(); var body = soap.SelectSingleNode("//soap:Body", namespaceMgr); if (body == null) { throw new HttpStatusException(HttpCode.InternalError); } var method = body.FirstChild; foreach (var p in method.ChildNodes) { var e = p as XmlElement; if (e == null) { continue; } sparams.Add(e.LocalName, e.InnerText.Trim()); } var env = new XmlDocument(); env.AppendChild(env.CreateXmlDeclaration("1.0", "utf-8", "yes")); var envelope = env.CreateElement("SOAP-ENV", "Envelope", NS_SOAPENV); env.AppendChild(envelope); envelope.SetAttribute( "encodingStyle", NS_SOAPENV, "http://schemas.xmlsoap.org/soap/encoding/"); var rbody = env.CreateElement("SOAP-ENV:Body", NS_SOAPENV); env.DocumentElement?.AppendChild(rbody); var code = HttpCode.Ok; try { IEnumerable <KeyValuePair <string, string> > result; switch (method.LocalName) { case "GetSearchCapabilities": result = HandleGetSearchCapabilities(); break; case "GetSortCapabilities": result = HandleGetSortCapabilities(); break; case "GetSystemUpdateID": result = HandleGetSystemUpdateID(); break; case "Browse": result = HandleBrowse(request, sparams); break; case "X_GetFeatureList": result = HandleXGetFeatureList(); break; case "X_SetBookmark": result = HandleXSetBookmark(sparams); break; case "GetCurrentConnectionIDs": result = HandleGetCurrentConnectionIDs(); break; case "GetCurrentConnectionInfo": result = HandleGetCurrentConnectionInfo(); break; case "GetProtocolInfo": result = HandleGetProtocolInfo(); break; case "IsAuthorized": result = HandleIsAuthorized(); break; case "IsValidated": result = HandleIsValidated(); break; case "RegisterDevice": result = HandleRegisterDevice(); break; default: throw new HttpStatusException(HttpCode.NotFound); } var response = env.CreateElement($"u:{method.LocalName}Response", method.NamespaceURI); rbody.AppendChild(response); foreach (var i in result) { var ri = env.CreateElement(i.Key); ri.InnerText = i.Value; response.AppendChild(ri); } } catch (Exception ex) { code = HttpCode.InternalError; var fault = env.CreateElement("SOAP-ENV", "Fault", NS_SOAPENV); var faultCode = env.CreateElement("faultcode"); faultCode.InnerText = "500"; fault.AppendChild(faultCode); var faultString = env.CreateElement("faultstring"); faultString.InnerText = ex.ToString(); fault.AppendChild(faultString); var detail = env.CreateDocumentFragment(); detail.InnerXml = "<detail><UPnPError xmlns=\"urn:schemas-upnp-org:control-1-0\"><errorCode>401</errorCode><errorDescription>Invalid Action</errorDescription></UPnPError></detail>"; fault.AppendChild(detail); rbody.AppendChild(fault); WarnFormat( "Invalid call: Action: {0}, Params: {1}, Problem {2}", method.LocalName, sparams, ex.Message); } var rv = new StringResponse(code, "text/xml", env.OuterXml); rv.Headers.Add("EXT", string.Empty); return(rv); }
public IResponse HandleRequest(IRequest request) { if (Authorizer != null && !IPAddress.IsLoopback(request.RemoteEndpoint.Address) && !Authorizer.Authorize( request.Headers, request.RemoteEndpoint, IP.GetMAC(request.RemoteEndpoint.Address) )) { throw new HttpStatusException(HttpCode.Denied); } var path = request.Path.Substring(prefix.Length); Debug(path); if (path == "description.xml") { return(new StringResponse( HttpCode.Ok, "text/xml", GenerateDescriptor(request.LocalEndPoint.Address) )); } if (path == "contentDirectory.xml") { return(new ResourceResponse( HttpCode.Ok, "text/xml", "contentdirectory" )); } if (path == "connectionManager.xml") { return(new ResourceResponse( HttpCode.Ok, "text/xml", "connectionmanager" )); } if (path == "MSMediaReceiverRegistrar.xml") { return(new ResourceResponse( HttpCode.Ok, "text/xml", "MSMediaReceiverRegistrar" )); } if (path == "control") { return(ProcessSoapRequest(request)); } if (path.StartsWith("file/", StringComparison.Ordinal)) { var id = path.Split('/')[1]; InfoFormat("Serving file {0}", id); var item = GetItem(id) as IMediaResource; return(new ItemResponse(prefix, request, item)); } if (path.StartsWith("cover/", StringComparison.Ordinal)) { var id = path.Split('/')[1]; InfoFormat("Serving cover {0}", id); var item = GetItem(id) as IMediaCover; return(new ItemResponse(prefix, request, item.Cover, "Interactive")); } if (path.StartsWith("subtitle/", StringComparison.Ordinal)) { var id = path.Split('/')[1]; InfoFormat("Serving subtitle {0}", id); var item = GetItem(id) as IMetaVideoItem; return(new ItemResponse(prefix, request, item.Subtitle, "Background")); } if (string.IsNullOrEmpty(path) || path == "index.html") { return(new Redirect(request, prefix + "index/0")); } if (path.StartsWith("index/", StringComparison.Ordinal)) { var id = path.Substring("index/".Length); var item = GetItem(id); return(ProcessHtmlRequest(item)); } if (request.Method == "SUBSCRIBE") { var res = new StringResponse(HttpCode.Ok, string.Empty); string notifySid; if (!request.Headers.TryGetValue("SID", out notifySid)) { notifySid = Guid.NewGuid().ToString(); } else { notifySid = notifySid.Remove(0, 5); } //string callback; Tuple <string, DateTime> subres; int timeout = System.Int32.Parse(request.Headers["timeout"].Remove(0, 7)); DateTime dtimeout = System.DateTime.Now.AddSeconds(timeout); if (!subscribers.TryGetValue(notifySid, out subres)) { if (request.Headers.ContainsKey("CALLBACK")) { string callback = request.Headers["CALLBACK"].Replace("<", "").Replace(">", ""); subscribers.Add(notifySid, new Tuple <string, DateTime>(callback, dtimeout)); Debug("Subscribe: " + notifySid + ": " + callback); } else { Error("SUBSCRIBE WTF: " + request.Headers); } } else { //RENEW subscribers[notifySid] = new Tuple <string, DateTime>(subres.Item1, dtimeout); } res.Headers.Add("SID", string.Format("uuid:{0}", notifySid)); res.Headers.Add("TIMEOUT", request.Headers["timeout"]); return(res); } if (request.Method == "UNSUBSCRIBE") { //TODO: remove from subscribers return(new StringResponse(HttpCode.Ok, string.Empty)); } WarnFormat("Did not understand {0} {1}", request.Method, path); throw new HttpStatusException(HttpCode.NotFound); }
public IResponse HandleRequest(IRequest request) { if (Authorizer != null && !IPAddress.IsLoopback(request.RemoteEndpoint.Address) && !Authorizer.Authorize( request.Headers, request.RemoteEndpoint, IP.GetMAC(request.RemoteEndpoint.Address) )) { throw new HttpStatusException(HttpCode.Denied); } var path = request.Path.Substring(Prefix.Length); Debug(path); if (path == "description.xml") { return(new StringResponse( HttpCode.Ok, "text/xml", GenerateDescriptor(request.LocalEndPoint.Address) )); } if (path == "contentDirectory.xml") { return(new ResourceResponse( HttpCode.Ok, "text/xml", "contentdirectory" )); } if (path == "connectionManager.xml") { return(new ResourceResponse( HttpCode.Ok, "text/xml", "connectionmanager" )); } if (path == "MSMediaReceiverRegistrar.xml") { return(new ResourceResponse( HttpCode.Ok, "text/xml", "MSMediaReceiverRegistrar" )); } if (path == "control") { return(ProcessSoapRequest(request)); } if (path.StartsWith("file/", StringComparison.Ordinal)) { var id = path.Split('/')[1]; var item = GetItem(id) as IMediaResource; InfoFormat("{0}", request.RemoteEndpoint.Address + " : " + item.Path); return(new ItemResponse(Prefix, request, item)); } if (path.StartsWith("cover/", StringComparison.Ordinal)) /* * var id = path.Split('/')[1]; * InfoFormat("Serving cover {0}", id); * var item = GetItem(id) as IMediaCover; * if (item == null) { * throw new HttpStatusException(HttpCode.NotFound); * } * return new ItemResponse(Prefix, request, item.Cover, "Interactive"); */ { throw new HttpStatusException(HttpCode.NotFound); } if (path.StartsWith("subtitle/", StringComparison.Ordinal)) { var id = path.Split('/')[1]; var item = GetItem(id) as IMetaVideoItem; InfoFormat("{0}", request.RemoteEndpoint.Address + " : " + item.Subtitle.Path); if (item == null) { throw new HttpStatusException(HttpCode.NotFound); } return(new ItemResponse(Prefix, request, item.Subtitle, "Background")); } if (string.IsNullOrEmpty(path) || path == "index.html") { return(new Redirect(request, Prefix + "index/0")); } if (path.StartsWith("index/", StringComparison.Ordinal)) { var id = path.Substring("index/".Length); var item = GetItem(id); return(ProcessHtmlRequest(item)); } if (request.Method == "SUBSCRIBE") { var res = new StringResponse(HttpCode.Ok, string.Empty); res.Headers.Add("SID", $"uuid:{Guid.NewGuid()}"); res.Headers.Add("TIMEOUT", request.Headers["timeout"]); return(res); } if (request.Method == "UNSUBSCRIBE") { return(new StringResponse(HttpCode.Ok, string.Empty)); } WarnFormat("Did not understand {0} {1}", request.Method, path); throw new HttpStatusException(HttpCode.NotFound); }
public IResponse HandleRequest(IRequest request) { if (Authorizer != null && !IPAddress.IsLoopback(request.RemoteEndpoint.Address) && !Authorizer.Authorize( request.Headers, request.RemoteEndpoint, IP.GetMAC(request.RemoteEndpoint.Address) )) { throw new HttpStatusException(HttpCode.Denied); } var path = request.Path.Substring(prefix.Length); Debug(path); if (path == "description.xml") { return new StringResponse( HttpCode.Ok, "text/xml", GenerateDescriptor(request.LocalEndPoint.Address) ); } if (path == "contentDirectory.xml") { return new ResourceResponse( HttpCode.Ok, "text/xml", "contentdirectory" ); } if (path == "connectionManager.xml") { return new ResourceResponse( HttpCode.Ok, "text/xml", "connectionmanager" ); } if (path == "MSMediaReceiverRegistrar.xml") { return new ResourceResponse( HttpCode.Ok, "text/xml", "MSMediaReceiverRegistrar" ); } if (path == "control") { return ProcessSoapRequest(request); } if (path.StartsWith("file/", StringComparison.Ordinal)) { var id = path.Split('/')[1]; InfoFormat("Serving file {0}", id); var item = GetItem(id) as IMediaResource; return new ItemResponse(prefix, request, item); } if (path.StartsWith("cover/", StringComparison.Ordinal)) { var id = path.Split('/')[1]; InfoFormat("Serving cover {0}", id); var item = GetItem(id) as IMediaCover; return new ItemResponse(prefix, request, item.Cover, "Interactive"); } if (path.StartsWith("subtitle/", StringComparison.Ordinal)) { var id = path.Split('/')[1]; InfoFormat("Serving subtitle {0}", id); var item = GetItem(id) as IMetaVideoItem; return new ItemResponse(prefix, request, item.Subtitle, "Background"); } if (string.IsNullOrEmpty(path) || path == "index.html") { return new Redirect(request, prefix + "index/0"); } if (path.StartsWith("index/", StringComparison.Ordinal)) { var id = path.Substring("index/".Length); var item = GetItem(id); return ProcessHtmlRequest(item); } if (request.Method == "SUBSCRIBE") { var res = new StringResponse(HttpCode.Ok, string.Empty); res.Headers.Add("SID", string.Format("uuid:{0}", Guid.NewGuid())); res.Headers.Add("TIMEOUT", request.Headers["timeout"]); return res; } if (request.Method == "UNSUBSCRIBE") { return new StringResponse(HttpCode.Ok, string.Empty); } WarnFormat("Did not understand {0} {1}", request.Method, path); throw new HttpStatusException(HttpCode.NotFound); }