proxy.ashx
上传用户:huazai0421
上传日期:2008-05-30
资源大小:405k
文件大小:8k
源码类别:

SilverLight

开发平台:

C#

  1. <%@ WebHandler Language="C#" Class="proxy" %>
  2. /*
  3.   This proxy page does not have any security checks. It is highly recommended
  4.   that a user deploying this proxy page on their web server, add appropriate
  5.   security checks, for example checking request path, username/password, target
  6.   url, etc.
  7. */
  8. using System;
  9. using System.Drawing;
  10. using System.IO;
  11. using System.Web;
  12. using System.Collections.Generic;
  13. using System.Text;
  14. using System.Xml.Serialization;
  15. using System.Web.Caching;
  16. /// <summary>
  17. /// Forwards requests to an ArcGIS Server REST resource. Uses information in
  18. /// the proxy.config file to determine properties of the server.
  19. /// </summary>
  20. public class proxy : IHttpHandler {
  21.     public void ProcessRequest (HttpContext context) {
  22.         HttpResponse response = context.Response;
  23.         // Get the URL requested by the client (take the entire querystring at once
  24.         //  to handle the case of the URL itself containing querystring parameters)
  25. string uri = Uri.UnescapeDataString(context.Request.QueryString.ToString());
  26.         // Get token, if applicable, and append to the request
  27.         string token = getTokenFromConfigFile(uri);
  28.         if (!String.IsNullOrEmpty(token))
  29.         {
  30.             if (uri.Contains("?"))
  31.                 uri += "&token=" + token;
  32.             else
  33.                 uri += "?token=" + token;
  34.         }
  35.         
  36. System.Net.WebRequest req = System.Net.WebRequest.Create(new Uri(uri));
  37. req.Method = context.Request.HttpMethod;
  38. ((System.Net.HttpWebRequest)req).Referer = "http://nielsen.esri.com/";
  39.            
  40.         // Set body of request for POST requests
  41.         if (context.Request.InputStream.Length > 0)
  42.         {
  43.             byte[] bytes = new byte[context.Request.InputStream.Length];
  44.             context.Request.InputStream.Read(bytes, 0, (int)context.Request.InputStream.Length);
  45.             req.ContentLength = bytes.Length;
  46.  req.ContentType = "application/x-www-form-urlencoded";
  47.             using (Stream outputStream = req.GetRequestStream())
  48.             {
  49.                 outputStream.Write(bytes, 0, bytes.Length);
  50.             }
  51.         }
  52.         // Send the request to the server
  53.         System.Net.WebResponse serverResponse = null;
  54.         try
  55.         {
  56.             serverResponse = req.GetResponse();
  57.         }
  58.         catch (System.Net.WebException webExc)
  59.         {
  60.             response.StatusCode = 500;
  61.             response.StatusDescription = webExc.Status.ToString();
  62.             response.Write(webExc.Response);
  63.             response.End();
  64.             return;
  65.         }
  66.         
  67.         // Set up the response to the client
  68.         if (serverResponse != null) {
  69.             response.ContentType = serverResponse.ContentType;
  70.             using (Stream byteStream = serverResponse.GetResponseStream())
  71.             {
  72.                 // Text response
  73.                 if (serverResponse.ContentType.Contains("text"))
  74.                 {
  75.                     using (StreamReader sr = new StreamReader(byteStream))
  76.                     {
  77.                         string strResponse = sr.ReadToEnd();
  78.                         response.Write(strResponse);
  79.                     }
  80.                 }
  81.                 else
  82.                 {
  83.                     // Binary response (image, lyr file, other binary file)
  84.                     BinaryReader br = new BinaryReader(byteStream);
  85.                     byte[] outb = br.ReadBytes((int)serverResponse.ContentLength);
  86.                     br.Close();
  87.                     // Tell client not to cache the image since it's dynamic
  88.                     response.CacheControl = "no-cache";
  89.                     // Send the image to the client
  90.                     // (Note: if large images/files sent, could modify this to send in chunks)
  91.                     response.OutputStream.Write(outb, 0, outb.Length);
  92.                 }
  93.                 serverResponse.Close();
  94.             }
  95.         }
  96.         response.End();
  97.     }
  98.  
  99.     public bool IsReusable {
  100.         get {
  101.             return false;
  102.         }
  103.     }
  104.     // Gets the token for a server URL from a configuration file
  105.     // TODO: ?modify so can generate a new short-lived token from username/password in the config file
  106.     private string getTokenFromConfigFile(string uri)
  107.     {
  108.         try
  109.         {
  110.             ProxyConfig config = ProxyConfig.GetCurrentConfig();
  111.             if (config != null)
  112.                 return config.GetToken(uri);
  113.             else
  114.                 throw new ApplicationException(
  115.                     "Proxy.config file does not exist at application root, or is not readable.");
  116.         }
  117.         catch (InvalidOperationException)
  118.         {
  119.             // Proxy is being used for an unsupported service (proxy.config has mustMatch="true")
  120.             HttpResponse response = HttpContext.Current.Response;
  121.             response.StatusCode = (int)System.Net.HttpStatusCode.Forbidden;
  122.             response.End();
  123.         }
  124.         catch (Exception e)
  125.         {
  126.             if (e is ApplicationException)
  127.                 throw e;
  128.             
  129.             // just return an empty string at this point
  130.             // -- may want to throw an exception, or add to a log file
  131.         }
  132.         
  133.         return string.Empty;
  134.     }
  135. }
  136. [XmlRoot("ProxyConfig")]
  137. public class ProxyConfig
  138. {
  139.     #region Static Members
  140.     private static object _lockobject = new object();
  141.     public static ProxyConfig LoadProxyConfig(string fileName)
  142.     {
  143.         ProxyConfig config = null;
  144.         lock (_lockobject)
  145.         {
  146.             if (System.IO.File.Exists(fileName))
  147.             {
  148.                 XmlSerializer reader = new XmlSerializer(typeof(ProxyConfig));
  149.                 using (System.IO.StreamReader file = new System.IO.StreamReader(fileName))
  150.                 {
  151.                     config = (ProxyConfig)reader.Deserialize(file);
  152.                 }
  153.             }
  154.         }
  155.         return config;
  156.     }
  157.     public static ProxyConfig GetCurrentConfig()
  158.     {
  159.         ProxyConfig config = HttpRuntime.Cache["proxyConfig"] as ProxyConfig;
  160.         if (config == null)
  161.         {
  162.             string fileName = GetFilename(HttpContext.Current);
  163.             config = LoadProxyConfig(fileName);
  164.             if (config != null)
  165.             {
  166.                 CacheDependency dep = new CacheDependency(fileName);
  167.                 HttpRuntime.Cache.Insert("proxyConfig", config, dep);
  168.             }
  169.         }
  170.         return config;
  171.     }
  172.     public static string GetFilename(HttpContext context)
  173.     {
  174.         return context.Server.MapPath("~/proxy.config");
  175.     }
  176.     #endregion
  177.     ServerUrl[] serverUrls;
  178.     bool mustMatch;
  179.     [XmlArray("serverUrls")]
  180.     [XmlArrayItem("serverUrl")]
  181.     public ServerUrl[] ServerUrls
  182.     {
  183.         get { return this.serverUrls; }
  184.         set { this.serverUrls = value; }
  185.     }
  186.     [XmlAttribute("mustMatch")]
  187.     public bool MustMatch
  188.     {
  189.         get { return mustMatch; }
  190.         set { mustMatch = value; }
  191.     }
  192.     public string GetToken(string uri)
  193.     {
  194.         foreach (ServerUrl su in serverUrls)
  195.         {
  196.             if (su.MatchAll && uri.StartsWith(su.Url, StringComparison.InvariantCultureIgnoreCase))
  197.             {
  198.                 return su.Token;
  199.             }
  200.             else
  201.             {
  202.                 if (String.Compare(uri, su.Url, StringComparison.InvariantCultureIgnoreCase) == 0)
  203.                     return su.Token;
  204.             }
  205.         }
  206.         if (mustMatch)
  207.             throw new InvalidOperationException();
  208.         return string.Empty;
  209.     }
  210. }
  211. public class ServerUrl
  212. {
  213.     string url;
  214.     bool matchAll;
  215.     string token;
  216.     [XmlAttribute("url")]
  217.     public string Url
  218.     {
  219.         get { return url; }
  220.         set { url = value; }
  221.     }
  222.     [XmlAttribute("matchAll")]
  223.     public bool MatchAll
  224.     {
  225.         get { return matchAll; }
  226.         set { matchAll = value; }
  227.     }
  228.     [XmlAttribute("token")]
  229.     public string Token
  230.     {
  231.         get { return token; }
  232.         set { token = value; }
  233.     }
  234. }