using CPE.App.Web.Code; using System; using System.Collections.Specialized; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Web; using System.Xml; namespace CPE.App.Web.Connect { /// /// Handles a basic request to the Connect service. /// public class Request { // Private private XmlDocument _xmlResults; private NameValueCollection _parameters = new NameValueCollection(); private Session _session = new Session(); private static string CleanHost(string url) { if (!url.StartsWith("http")) url = "http://" + url; return url.ToLower(); } /// /// The action to perform against the service. /// /// common-info public string Action { get; set; } /// /// The parameters to pass with the action for this request. /// public NameValueCollection Parameters { get { return _parameters; } set { _parameters = value; } } /// /// The Session settings to contact the service. /// public Session Session { get { return _session; } set { _session = value; } } /// /// Returns the raw XmlDocument that was returned from the service. /// public XmlDocument XmlResults { get { return _xmlResults; }} /// /// Returns the current status of the request. /// public Status Status { get { // Default Status status = Status.Unknown; // Has a response been received? if(HasResponse) { // Parse the response for the status string statusCode = _xmlResults.SelectSingleNode("//status").Attributes["code"].Value; switch(statusCode) { case "ok": status = Status.OK; break; case "invalid": status = Status.Invalid; break; case "no-access": status = Status.NoAccess; break; case "no-data": status = Status.NoData; break; case "too-much-data": status = Status.TooMuchData; break; } } return status; } } /// /// Returns whether a response has been received for this request. /// public bool HasResponse { get { return (_xmlResults != null); } } /// /// Returns the response headers for this request. Useful for retrieving the session key from a login request. /// public WebHeaderCollection ResponseHeaders { get; private set; } /// /// Initializes an empty request. /// public Request() { } /// /// Initializes a request. /// /// The hostname to connect to. /// The action to perform. public Request(string hostname, string action) { Session.Hostname = hostname; Action = action; } /// /// Initializes the request. /// /// The session object to connect with. /// The action to perform. public Request(Session session, string action) { Session = session; Action = action; } private string _url = null; public string Url { get { return _url; } } /// /// Sends the request to the service and retrieves the results. /// /// Returns true if the request came back or false if an exception was thrown. public virtual bool Execute() { try { // Example URL: http://connectpro41408666.acrobat.com/api/xml?action=common-info // Build URL var host = CleanHost(Session.Hostname); var url = new StringBuilder(string.Format("{0}/api/xml?action={1}", host, Action)); // Is a session key set? if(Session.SessionKey != null) Parameters.Add("session", Session.SessionKey); // Add parameters to querystring for(int i = 0; i < Parameters.Count; i++) { for(int x = 0; x < Parameters.GetValues(i).Length; x++) { url.AppendFormat("&{0}={1}", HttpUtility.UrlEncode(Parameters.Keys[i]), HttpUtility.UrlEncode(Parameters.GetValues(i)[x])); } } // Ignore SSL validation errors //ServicePointManager.ServerCertificateValidationCallback = IgnoreInvalidSSL; // Retrieve XML string xml = null; using(var request = new WebClient() { UseDefaultCredentials = true, Encoding = Encoding.UTF8 }) { // Is a proxy required? if(Session.Proxy != null) request.Proxy = new WebProxy(Session.Proxy, true) { UseDefaultCredentials = true }; //Extensions.LogServiceCall("[Request][Execute]", String.Format("url = {0}", url.ToString())); try { // System.IO.File.AppendAllText("adobeconnect_log.txt", url.ToString() + Environment.NewLine); } catch { } // Download try { xml = request.DownloadString(url.ToString()); ResponseHeaders = request.ResponseHeaders; } catch(Exception ex) { //var log = new ExceptionLogController(); //log.AddLog(ex, ExceptionLogController.ExceptionLogType.GENERAL_EXCEPTION); //log.AddLog(new Exception(url.ToString()), ExceptionLogController.ExceptionLogType.GENERAL_EXCEPTION); Extensions.LogServiceError("[Request][Execute]", ex); goto theend; } } // Load XML _xmlResults = new XmlDocument(); _xmlResults.LoadXml(xml); _url = url.ToString(); return true; } catch { } theend: _xmlResults = null; ResponseHeaders = null; return false; } /// /// Overrides the default vertifcation for SSL certificates so that they will always be accepted. /// private static bool IgnoreInvalidSsl(object sender, System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors errors) { return true; } /// /// Returns the session key that is returned in the ResponseHeaders from Connect. /// /// The session key, if found. Returns an empty string if not found. public string ExtractSessionKey() { // Default to returning an empty string if the key isn't found string session = string.Empty; // Does the cookie header exist? if(ResponseHeaders != null && ResponseHeaders["Set-Cookie"] != null) { // Example session cookie // BREEZESESSION=Sbreez9u75m9zfau4pi8m8;HttpOnly;domain=.acrobat.com;path=/ // Capture session key var regex = new Regex(@"BREEZESESSION=(?\w*);"); Match match = regex.Match(ResponseHeaders["Set-Cookie"]); if(match.Success) session = match.Groups["session"].Value; } return session; } } /// /// Specifies the status of the request. /// public enum Status { Unknown, OK, Invalid, NoAccess, NoData, TooMuchData } public static class ScoTypes { public enum Types { Archive, Attachment, Authorware, Captivate, Content, Course, Curriculum, Event, ExternalEvent, Flv, Folder, Image, Link, Meeting, Presentation, Producer, Session, Swf, Tree, Unknown } public static Types TryParse(string type) { try { switch (type) { case "archive": return Types.Archive; case "attachment": return Types.Attachment; case "authorware": return Types.Authorware; case "captivate": return Types.Captivate; case "content": return Types.Content; case "course": return Types.Course; case "curriculum": return Types.Curriculum; case "event": return Types.Event; case "external-event": return Types.ExternalEvent; case "flv": return Types.Flv; case "folder": return Types.Folder; case "image": return Types.Image; case "link": return Types.Link; case "meeting": return Types.Meeting; case "presentation": return Types.Presentation; case "producer": return Types.Producer; case "session": return Types.Session; case "swf": return Types.Swf; case "tree": return Types.Tree; default: return Types.Content; } } catch (Exception) { } return Types.Unknown; } } }