initial commit
[CPE_learningsite] / CPE / CPE.App / CPE.App.Web / Connect / Request.cs
1 using CPE.App.Web.Code;
2 using System;
3 using System.Collections.Specialized;
4 using System.Net;
5 using System.Text;
6 using System.Text.RegularExpressions;
7 using System.Web;
8 using System.Xml;
9
10 namespace CPE.App.Web.Connect {
11
12         /// <summary>
13         /// Handles a basic request to the Connect service.
14         /// </summary>
15         public class Request {
16
17                 // Private
18                 private XmlDocument _xmlResults;
19                 private NameValueCollection _parameters = new NameValueCollection();
20                 private Session _session = new Session();
21
22                 private static string CleanHost(string url) {
23                         if (!url.StartsWith("http"))
24                                 url = "http://" + url;
25                         return url.ToLower();
26                 }
27
28                 /// <summary>
29                 /// The action to perform against the service.
30                 /// </summary>
31                 /// <example>common-info</example>
32                 public string Action { get; set; }
33
34                 /// <summary>
35                 /// The parameters to pass with the action for this request.
36                 /// </summary>
37                 public NameValueCollection Parameters {
38                         get {
39                                 return _parameters;
40                         }
41                         set {
42                                 _parameters = value;
43                         }
44                 }
45
46                 /// <summary>
47                 /// The Session settings to contact the service.
48                 /// </summary>
49                 public Session Session {
50                         get {
51                                 return _session;
52                         }
53                         set {
54                                 _session = value;
55                         }
56                 }
57
58                 /// <summary>
59                 /// Returns the raw XmlDocument that was returned from the service.
60                 /// </summary>
61                 public XmlDocument XmlResults { get { return _xmlResults; }}
62
63                 /// <summary>
64                 /// Returns the current status of the request.
65                 /// </summary>
66                 public Status Status {
67                         get {
68                                 
69                                 // Default
70                                 Status status = Status.Unknown;
71
72                                 // Has a response been received?
73                                 if(HasResponse) {
74
75                                         // Parse the response for the status
76                                         string statusCode = _xmlResults.SelectSingleNode("//status").Attributes["code"].Value;
77                                         
78                                         switch(statusCode)  {
79                                                 case "ok": 
80                                                         status = Status.OK;
81                                                         break;
82                                                 case "invalid":
83                                                         status = Status.Invalid;
84                                                         break;
85                                                 case "no-access":
86                                                         status = Status.NoAccess;
87                                                         break;
88                                                 case "no-data":
89                                                         status = Status.NoData;
90                                                         break;
91                                                 case "too-much-data":
92                                                         status = Status.TooMuchData;
93                                                         break;
94                                         }
95                                 }
96
97                                 return status;
98                         }
99                 }
100
101                 /// <summary>
102                 /// Returns whether a response has been received for this request.
103                 /// </summary>
104                 public bool HasResponse { get { return (_xmlResults != null); } }
105
106                 /// <summary>
107                 /// Returns the response headers for this request. Useful for retrieving the session key from a login request.
108                 /// </summary>
109                 public WebHeaderCollection ResponseHeaders { get; private set; }
110
111                 /// <summary>
112                 /// Initializes an empty request.
113                 /// </summary>
114                 public Request() { }
115
116                 /// <summary>
117                 /// Initializes a request.
118                 /// </summary>
119                 /// <param name="hostname">The hostname to connect to.</param>
120                 /// <param name="action">The action to perform.</param>
121                 public Request(string hostname, string action) {
122                         Session.Hostname = hostname;
123                         Action = action;
124                 }
125
126                 /// <summary>
127                 /// Initializes the request.
128                 /// </summary>
129                 /// <param name="session">The session object to connect with.</param>
130                 /// <param name="action">The action to perform.</param>
131                 public Request(Session session, string action) {
132                         Session = session;
133                         Action = action;
134                 }
135
136
137                 private string _url = null;
138                 public string Url
139                 {
140                         get
141                         {
142                                 return _url;
143                         }
144                 }
145
146                 /// <summary>
147                 /// Sends the request to the service and retrieves the results.
148                 /// </summary>
149                 /// <returns>Returns true if the request came back or false if an exception was thrown.</returns>
150                 public virtual bool Execute() {
151
152                         try {
153
154                                 // Example URL: http://connectpro41408666.acrobat.com/api/xml?action=common-info        
155
156                                 // Build URL
157                                 var host = CleanHost(Session.Hostname);
158                                 var url = new StringBuilder(string.Format("{0}/api/xml?action={1}", host, Action));
159
160                                 // Is a session key set?
161                                 if(Session.SessionKey != null)
162                                         Parameters.Add("session", Session.SessionKey);
163
164                                 // Add parameters to querystring
165                                 for(int i = 0; i < Parameters.Count; i++) {
166                                         for(int x = 0; x < Parameters.GetValues(i).Length; x++) {
167                                                 url.AppendFormat("&{0}={1}", HttpUtility.UrlEncode(Parameters.Keys[i]), HttpUtility.UrlEncode(Parameters.GetValues(i)[x]));
168                                         }
169                                 }
170
171                                 // Ignore SSL validation errors
172                                 //ServicePointManager.ServerCertificateValidationCallback = IgnoreInvalidSSL;
173
174                                 // Retrieve XML
175                                 string xml = null;
176
177                                 using(var request = new WebClient() { UseDefaultCredentials = true, Encoding = Encoding.UTF8 }) {
178
179                                         // Is a proxy required?
180                                         if(Session.Proxy != null)
181                                                 request.Proxy = new WebProxy(Session.Proxy, true) { UseDefaultCredentials = true };
182
183                                         //Extensions.LogServiceCall("[Request][Execute]", String.Format("url = {0}", url.ToString()));
184
185                                         try
186                                         {
187                                                 // System.IO.File.AppendAllText("adobeconnect_log.txt", url.ToString() + Environment.NewLine);
188                                         }
189                                         catch
190                                         {
191                                         }
192
193                                         // Download
194                                         try
195                                         {
196                                                 xml = request.DownloadString(url.ToString());
197                                                 ResponseHeaders = request.ResponseHeaders;
198                                         }
199                                         catch(Exception ex)
200                                         {
201                                                 //var log = new ExceptionLogController();
202                                                 //log.AddLog(ex, ExceptionLogController.ExceptionLogType.GENERAL_EXCEPTION);
203                                                 //log.AddLog(new Exception(url.ToString()), ExceptionLogController.ExceptionLogType.GENERAL_EXCEPTION);
204                                                 Extensions.LogServiceError("[Request][Execute]", ex);
205                                                 goto theend;
206                                         }
207                                 }
208
209                                 // Load XML
210                                 _xmlResults = new XmlDocument();
211                                 _xmlResults.LoadXml(xml);
212                                 _url = url.ToString();
213                                 
214                                 return true;                    
215                         }
216                         catch
217                         {
218                                 
219                         }
220                         theend:
221                         _xmlResults = null;
222                         ResponseHeaders = null;
223                         return false;
224                 }
225
226                 /// <summary>
227                 /// Overrides the default vertifcation for SSL certificates so that they will always be accepted.
228                 /// </summary>
229                 private static bool IgnoreInvalidSsl(object sender, System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors errors) {
230                         return true;
231                 }
232
233                 /// <summary>
234                 /// Returns the session key that is returned in the ResponseHeaders from Connect.
235                 /// </summary>
236                 /// <returns>The session key, if found. Returns an empty string if not found.</returns>
237                 public string ExtractSessionKey() {
238
239                         // Default to returning an empty string if the key isn't found
240                         string session = string.Empty;
241
242                         // Does the cookie header exist?
243                         if(ResponseHeaders != null && ResponseHeaders["Set-Cookie"] != null) {
244
245                                 // Example session cookie
246                                 // BREEZESESSION=Sbreez9u75m9zfau4pi8m8;HttpOnly;domain=.acrobat.com;path=/
247
248                                 // Capture session key
249                                 var regex = new Regex(@"BREEZESESSION=(?<session>\w*);");
250                                 Match match = regex.Match(ResponseHeaders["Set-Cookie"]);
251
252                                 if(match.Success)
253                                         session = match.Groups["session"].Value;
254                         }
255
256                         return session;
257                 }
258         }
259
260         /// <summary>
261         /// Specifies the status of the request.
262         /// </summary>
263         public enum Status {
264                 Unknown,
265                 OK,
266                 Invalid,
267                 NoAccess,
268                 NoData,
269                 TooMuchData
270         }
271
272         public static class ScoTypes
273         {
274                 public enum Types
275                 {
276                         Archive,
277                         Attachment,
278                         Authorware,
279                         Captivate,
280                         Content,
281                         Course,
282                         Curriculum,
283                         Event,
284                         ExternalEvent,
285                         Flv,
286                         Folder,
287                         Image,
288                         Link,
289                         Meeting,
290                         Presentation,
291                         Producer,
292                         Session,
293                         Swf,
294                         Tree,
295                         Unknown
296                 }
297
298                 public static Types TryParse(string type)
299                 {
300                         try
301                         {
302                                 switch (type)
303                                 {
304                                         case "archive":
305                                                 return Types.Archive;
306                                         case "attachment":
307                                                 return Types.Attachment;
308                                         case "authorware":
309                                                 return Types.Authorware;
310                                         case "captivate":
311                                                 return Types.Captivate;
312                                         case "content":
313                                                 return Types.Content;
314                                         case "course":
315                                                 return Types.Course;
316                                         case "curriculum":
317                                                 return Types.Curriculum;
318                                         case "event":
319                                                 return Types.Event;
320                                         case "external-event":
321                                                 return Types.ExternalEvent;
322                                         case "flv":
323                                                 return Types.Flv;
324                                         case "folder":
325                                                 return Types.Folder;
326                                         case "image":
327                                                 return Types.Image;
328                                         case "link":
329                                                 return Types.Link;
330                                         case "meeting":
331                                                 return Types.Meeting;
332                                         case "presentation":
333                                                 return Types.Presentation;
334                                         case "producer":
335                                                 return Types.Producer;
336                                         case "session":
337                                                 return Types.Session;
338                                         case "swf":
339                                                 return Types.Swf;
340                                         case "tree":
341                                                 return Types.Tree;
342                                         default:
343                                                 return Types.Content;
344                                 }
345                         }
346                         catch (Exception)
347                         {
348                                 
349                         }
350                         return Types.Unknown;
351                 }
352         }
353         
354 }