[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