diff --git a/gateway/apollo_management.go b/gateway/apollo_management.go
new file mode 100644
index 0000000..50a1e38
--- /dev/null
+++ b/gateway/apollo_management.go
@@ -0,0 +1,42 @@
+package gateway
+
+import (
+ "encoding/xml"
+ "strings"
+)
+
+type apolloLaunchResponse struct {
+ StatusCode string `xml:"status_code,attr"`
+ SessionURL string `xml:"sessionUrl0"`
+}
+
+func apolloInventoryContains(data []byte, applicationID string) bool {
+ if len(data) == 0 || len(data) > 64<<10 || applicationID == "" {
+ return false
+ }
+ var document struct {
+ Applications []struct {
+ ID string `xml:"ID"`
+ } `xml:"App"`
+ }
+ if xml.Unmarshal(data, &document) != nil {
+ return false
+ }
+ for _, application := range document.Applications {
+ if strings.TrimSpace(application.ID) == applicationID {
+ return true
+ }
+ }
+ return false
+}
+
+func parseApolloLaunchResponse(data []byte) (apolloLaunchResponse, error) {
+ if len(data) == 0 || len(data) > 64<<10 {
+ return apolloLaunchResponse{}, ErrProviderMalformed
+ }
+ var response apolloLaunchResponse
+ if xml.Unmarshal(data, &response) != nil || response.StatusCode != "200" || strings.TrimSpace(response.SessionURL) == "" {
+ return apolloLaunchResponse{}, ErrProviderMalformed
+ }
+ return response, nil
+}
diff --git a/gateway/apollo_management_test.go b/gateway/apollo_management_test.go
new file mode 100644
index 0000000..5db51a3
--- /dev/null
+++ b/gateway/apollo_management_test.go
@@ -0,0 +1,16 @@
+package gateway
+
+import "testing"
+
+func TestApolloInventoryAndLaunchResponseRequireExactApplicationAndSuccess(t *testing.T) {
+ inventory := []byte(`4142`)
+ if !apolloInventoryContains(inventory, "42") || apolloInventoryContains(inventory, "420") {
+ t.Fatal("apolloInventoryContains() did not require an exact inventory ID")
+ }
+ if _, err := parseApolloLaunchResponse([]byte(`rtspenc://apollo.test:47984`)); err != nil {
+ t.Fatalf("parseApolloLaunchResponse() error = %v", err)
+ }
+ if _, err := parseApolloLaunchResponse([]byte(`rtspenc://apollo.test:47984`)); err == nil {
+ t.Fatal("parseApolloLaunchResponse() accepted a denied launch")
+ }
+}