Mod xml curl C sharp example

From FreeSWITCH Wiki
Jump to: navigation, search


Warning

Superseded by https://confluence.freeswitch.org/display/FREESWITCH/mod_xml_curl+C+sharp+example

 


The following page will show you how to include a webserver in your .NET application, and how to let the webserver generate a dialplan.

Contents

Requirements

MiniHTTPd is a C# project released under the artistic license. It is coded in .NET 1.1 and will give some warnings in .NET 2.0.

It can be downloaded from here: http://www.codeproject.com/KB/IP/minihttpd.aspx

Implementation

First of all, you need to download and install MiniHTTPd. The next thing to do is to create a new project (whatever flavor you like), and add this class to it.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using MiniHttpd;

namespace FreeSwitch
{
    /// <summary>
    /// The following class is coded by Jonas Gauffin.
    /// 
    /// </summary>
    class FreeSwitchCurlPage : IFile
    {
        private IDirectory parent = null;
        public delegate string HandleQuery(UriQuery query);
        public event HandleQuery OnGetDialplan;
        public event HandleQuery OnGetUserDirectory;       

        public FreeSwitchCurlPage()
        {
        }
        public FreeSwitchCurlPage(IDirectory parent)
        {
            this.parent = parent;
        }

        /// <summary>
        /// Gets the name of the entry.
        /// </summary>
        public string Name
        {
            get { return "curl.fetch"; }
        }

        /// <summary>
        /// Gets the parent directory of the object.
        /// </summary>
        public IDirectory Parent
        {
            get { return parent; }
        }

        /// <summary>
        /// Called when the file is requested by a client.
        /// </summary>
        /// <param name="request">The <see cref="HttpRequest"/> requesting the file.</param>
        /// <param name="directory">The <see cref="IDirectory"/> of the parent directory.</param>
        public void OnFileRequested(HttpRequest request, IDirectory directory)
        {
            UriQuery queryString = new UriQuery(GetPostData(request));
            if (queryString["section"] == "dialplan")
            {
                if (OnGetDialplan != null)
                {
                    string dialplan = OnGetDialplan.Invoke(queryString);
                    request.Response.BeginChunkedOutput();
                    System.IO.StreamWriter writer = new StreamWriter(request.Response.ResponseContent);
                    writer.Write(dialplan);
                    writer.Flush();
                    writer.Close();
                }
            }
            else if (queryString["section"] == "directory")
            {
                if (OnGetUserDirectory != null)
                {
                    string userDirectory = OnGetUserDirectory.Invoke(queryString);
                    request.Response.BeginChunkedOutput();
                    System.IO.StreamWriter writer = new StreamWriter(request.Response.ResponseContent);
                    writer.Write(userDirectory);
                    writer.Flush();
                    writer.Close();
                }

            }
        }

        /// <summary>
        /// Gets the MIME type of the content.
        /// </summary>
        public string ContentType
        {
            get
            {
                return "text/xml";
            }
        }

        public void Dispose()
        {
        }

        void SetParent(IDirectory parent)
        {
            this.parent = parent;
        }


        private string GetPostData(HttpRequest request)
        {
            try
            {
                using (StreamReader reader = new StreamReader(request.PostData))
                {
                    return reader.ReadToEnd();
                }
            }
            catch (ArgumentException err)
            {
                Console.WriteLine(err.ToString());
            }
            return "";
        }
    }
}

Next, you should add the following class which setups MiniHTTPd with our own page handler.

using System;
using MiniHttpd;
using System.IO;

namespace FreeSwitch
{
 	/// <summary>
	/// Summary description for HttpTest.
	/// </summary>
	public class ModCurlHandler
	{
        private HttpWebServer server = null;

        public ModCurlHandler()
		{
            server = new HttpWebServer(8080);            

            // Setup directories
            VirtualDirectory root = new VirtualDirectory("/", null);
            server.Root = root;

            // We want curl to call http://localhost:8080/freeswitch/curl.fetch
            VirtualDirectory dir = new FreeSwitchVirtualDirectory("freeswitch", root);
            FreeSwitchCurlPage curlPage = new FreeSwitchCurlPage(dir);
            curlPage.OnGetDialplan += OnGetDialplan;
            dir.AddFile(curlPage);
            root.AddDirectory(dir);
		}

        public void Start()
        {
            server.Start();
        }

        public void Stop()
        {
            server.Stop();
        }

        protected string OnGetDialplan(UriQuery query)
        {
            return "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\r\n" +
                    "<document type=\"freeswitch/xml\">\r\n" +
                    "  <section name=\"dialplan\" description=\"RE Dial Plan For FreeSwitch\">\r\n" +
                    "    <context name=\"default\">\r\n" +
                    "      <extension name=\"test9\">\r\n" +
                    "        <condition field=\"destination_number\" expression=\"^1111$\">\r\n" +
                    "          <action application=\"playback\" data=\"C:\\temp\\sounds\\tt-monkeys.wav\"/>\r\n" +
                    "        </condition>\r\n" +
                    "      </extension>\r\n" +
                    "    </context>\r\n" +
                    "  </section>\r\n" +
                    "</document>\r\n";
        }
	}
}

You should change the OnGetDialplan to do something useful=) For instance, fetch actions from the database or something like that.

Configuration

Next, you need to configure mod_xml_curl to fetch the dialplan from our code. That configuration should look like this:

<configuration name="xml_curl.conf" description="cURL XML Gateway">
  <bindings>
    <binding name="dialplan fetcher">
      <param name="gateway-url" value="http://localhost:8080/freeswitch/curl.fetch" bindings="dialplan"/>
    </binding>
  </bindings>
</configuration>

See Also