[vlma-devel] commit: Validate orders before trying to run them. (Adrien Grand )
git version control
git at videolan.org
Sat Dec 26 14:53:54 CET 2009
vlma | branch: master | Adrien Grand <jpountz at videolan.org> | Sat Dec 26 14:50:31 2009 +0100| [16562d47bbae2d43b5d02f9e6c06af7d1e9a74bc] | committer: Adrien Grand
Validate orders before trying to run them.
> http://git.videolan.org/gitweb.cgi/vlma.git/?a=commit;h=16562d47bbae2d43b5d02f9e6c06af7d1e9a74bc
---
vlma-watchdog/src/validation.py | 105 +++++++++++++++++++++++++++++++++++++++
vlma-watchdog/src/web.py | 13 +++++-
vlma-watchdog/test/add_order.sh | 2 +-
3 files changed, 118 insertions(+), 2 deletions(-)
diff --git a/vlma-watchdog/src/validation.py b/vlma-watchdog/src/validation.py
new file mode 100644
index 0000000..c197eb3
--- /dev/null
+++ b/vlma-watchdog/src/validation.py
@@ -0,0 +1,105 @@
+#! /usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import conf, re
+from streamer.api import *
+
+NUMERIC_RE = re.compile("\d+")
+IPV4_RE = re.compile("(\d+)\.(\d+)\.(\d+)\.(\d+)")
+IPV6_RE = re.compile("([A-Fa-f0-9]*[:]{1,2})+[A-Fa-f0-9]*")
+ID_RE = re.compile("[A-Za-z0-9]+")
+
+class ValidationException(Exception):
+
+ def __init__(self, message=None):
+ Exception.__init__(self, message)
+
+
+def validate_order(order):
+ # Validate the id
+ match = ID_RE.match(order.id)
+ if match is None or match.group() != order.id:
+ raise ValidationException("the id of the order is not valid: '%s'" %order.id)
+
+ # Check whether the streamer exists
+ if not order.streamer is None:
+ for streamer in conf.STREAMERS:
+ if streamer.id == order.streamer:
+ break
+ raise ValidationException("No such streamer: '%s'" %order.streamer)
+
+ for src, dests in order.programs.items():
+ if isinstance(order, DVBOrder) and NUMERIC_RE.match(src) is None:
+ # DVB channels have a SID as src which is an integer formatted as a string
+ raise ValidationException("'src' has to be an integer for DVB channels: '%s' is not valid" %src)
+ for dest in dests:
+ validate_dest(order, dest)
+
+
+def validate_dest(order, dest):
+ # Check IP
+ match_v4 = IPV4_RE.match(dest.ip)
+ match_v6 = IPV6_RE.match(dest.ip)
+ if match_v4 is None and match_v6 is None:
+ raise ValidationException("'%s' is not a valid IP address" %dest.ip)
+ elif not match_v4 is None:
+ # TODO: more checks
+ if match_v4.group() != dest.ip:
+ raise ValidationException("'%s' is not a valid IPv4 address" %dest.ip)
+ else:
+ # TODO: more checks
+ if match_v6.group() != dest.ip:
+ raise ValidationException("'%s' is not a valid IPv6 address" %dest.ip)
+
+ check_streaming(order, dest, dest.streaming)
+ if not dest.transcoding is None:
+ check_transcoding(order, dest, dest.transcoding)
+ if not dest.announcing is None:
+ check_announcing(order, dest, dest.announcing)
+
+
+def check_streaming(order, dest, streaming):
+ # Check the type
+ supported_types = ["broadcast"]
+ if isinstance(order, FilesOrder):
+ supported_types.append("vod")
+ if not streaming.type in supported_types:
+ raise ValidationException("'%s' is not a valid streaming type" %streaming.type)
+
+ # Check the protocol
+ if streaming.type == "broadcast":
+ supported_protocols = ["udp", "rtp", "http"]
+ if not streaming.protocol in supported_protocols:
+ raise ValidationException("'%s' protocol is not supported for broadcasts" %streaming.protocol)
+ else:
+ if streaming.protocol != "rtsp":
+ raise ValidationException("'%s' protocol is not supported for VoD" %streaming.protocol)
+
+ # Check the encapsulation
+ supported_mux = ["ts", "ogg", "asf", "raw"]
+ if streaming.mux not in supported_mux:
+ raise ValidationException("'%s' mux is not supported" %streaming.mux)
+
+
+def check_transcoding(order, dest, transcoding):
+ # Check the video codec
+ supported_vcodecs = ["mp1v", "mp2v", "mp4v", "h264"]
+ if not transcoding.vcodec in supported_vcodecs:
+ raise ValidationException("video codec '%s' is not supported" %transcoding.vcodec)
+
+ # Check the audio codec
+ supported_vcodecs = ["mpga", "a52", "mp3", "mp4a"]
+ if not transcoding.vcodec in supported_vcodecs:
+ raise ValidationException("audio codec '%s' is not supported" %transcoding.acodec)
+
+
+def check_announcing(order, dest, annoucing):
+ # Check the type
+ supported_types = ["sap"]
+ if not annoucing.type in supported_types:
+ raise ValidationException("annoucing type '%s' is not supported" %annoncing.type)
+
+ if announcing.type == "sap" and dest.streaming.protocol not in ["udp", "rtp"]:
+ raise ValidationException("SAP announces can only be used with multicast streaming, %s found" %dest.streaming.protocol)
+
+
diff --git a/vlma-watchdog/src/web.py b/vlma-watchdog/src/web.py
index 928550c..2a75591 100644
--- a/vlma-watchdog/src/web.py
+++ b/vlma-watchdog/src/web.py
@@ -1,7 +1,7 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
-import conf, constants, logging, threading, serialization, sys, utils
+import conf, constants, logging, threading, serialization, sys, utils, validation
from streamer.api import *
try:
from twisted.web import server, resource, static
@@ -184,6 +184,8 @@ class OrderAddResource(AuthenticationRequiredResource):
request.setHeader('Content-type', 'text/xml')
buf = StringBuffer()
buf.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
+
+ # Parse the incoming XML
try:
order = serialization.order_from_xml(xml)
except serialization.SerializationException, e:
@@ -192,6 +194,15 @@ class OrderAddResource(AuthenticationRequiredResource):
serialization.error_to_xml(error, buf)
return str(buf)
+ # Validate the resulting object
+ try:
+ validation.validate_order(order)
+ except validation.ValidationException, e:
+ error = Error(ErrorCode.BAD_REQUEST, "Request not valid: %s" %str(e))
+ request.setResponseCode(error.code.http_status)
+ serialization.error_to_xml(error, buf)
+ return str(buf)
+
for streamer in self.streamers:
if streamer.orders.has_key(order.id):
try:
diff --git a/vlma-watchdog/test/add_order.sh b/vlma-watchdog/test/add_order.sh
index 6e83c04..f777c2a 100755
--- a/vlma-watchdog/test/add_order.sh
+++ b/vlma-watchdog/test/add_order.sh
@@ -2,4 +2,4 @@
# Add a DVB-S order
-curl -d "<dvbs-order><id>order_id</id><ttl>12</ttl><adapter>0</adapter><frequency>0</frequency><fec>9</fec><voltage>13</voltage><srate>0</srate><dvb-bandwidth>8</dvb-bandwidth><programs><program><src>1249</src><dest><ip>0.0.0.0</ip><port>1234</port><streaming><type>broadcast</type><protocol>udp</protocol><mux>raw</mux></streaming></dest><dest><streaming><type>broadcast</type><protocol>udp</protocol><mux>raw</mux></streaming></dest></program><program><src>1250</src><dest><streaming><type>broadcast</type><protocol>udp</protocol><mux>raw</mux></streaming></dest></program></programs></dvbs-order>" --user videolan:admin http://localhost:4213/order/add
+curl -d "<dvbs-order><id>orderid</id><ttl>12</ttl><adapter>0</adapter><frequency>0</frequency><fec>9</fec><voltage>13</voltage><srate>0</srate><dvb-bandwidth>8</dvb-bandwidth><programs><program><src>1249</src><dest><ip>0.0.0.0</ip><port>1234</port><streaming><type>broadcast</type><protocol>udp</protocol><mux>raw</mux></streaming></dest><dest><streaming><type>broadcast</type><protocol>udp</protocol><mux>raw</mux></streaming></dest></program><program><src>1250</src><dest><streaming><type>broadcast</type><protocol>udp</protocol><mux>raw</mux></streaming></dest></program></programs></dvbs-order>" --user videolan:admin http://localhost:4213/order/add
More information about the vlma-devel
mailing list