WebUtils.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. using System;
  2. using System.Drawing;
  3. using System.Globalization;
  4. using System.IO;
  5. using System.Net;
  6. using System.Text;
  7. using System.Web;
  8. using System.Web.UI.WebControls;
  9. using System.Xml;
  10. namespace FastReport.Web
  11. {
  12. /// <summary>
  13. ///
  14. /// </summary>
  15. public static class WebUtils
  16. {
  17. /// <summary>
  18. /// Contain the filename of httphandler
  19. /// </summary>
  20. public const string HandlerFileName = "FastReport.Export.axd";
  21. internal const string PicsPrefix = "frximg";
  22. internal const string PrintPrefix = "frxprint";
  23. internal const string ReportPrefix = "frxreport";
  24. internal const string StartupScriptName = "FrxStartup";
  25. internal const string ConstID = "ID";
  26. internal const string DefaultCreator = "FastReport";
  27. internal const string DefaultProducer = "FastReport .NET";
  28. internal const string HiddenIDSuffix = "FRID";
  29. /// <summary>
  30. /// Determines whether the path is an absolute physical path.
  31. /// </summary>
  32. /// <param name="path">The path to check.</param>
  33. /// <returns><b>true</b> if the path is absolute physical path.</returns>
  34. public static bool IsAbsolutePhysicalPath(string path)
  35. {
  36. if ((path == null) || (path.Length < 3))
  37. {
  38. return false;
  39. }
  40. return Path.IsPathRooted(path);
  41. }
  42. /// <summary>
  43. ///
  44. /// </summary>
  45. /// <param name="unit"></param>
  46. /// <returns></returns>
  47. public static string ToHtmlString(Unit unit)
  48. {
  49. switch (unit.Type)
  50. {
  51. case UnitType.Pixel:
  52. return unit.Value + "px";
  53. case UnitType.Percentage:
  54. return unit.Value + "%";
  55. default:
  56. return unit.Value.ToString();
  57. }
  58. }
  59. /// <summary>
  60. /// Returns the HTML color representation;
  61. /// </summary>
  62. /// <param name="color"></param>
  63. /// <returns></returns>
  64. public static string HTMLColor(Color color)
  65. {
  66. if (color == Color.Transparent)
  67. return "transparent";
  68. #if DOTNET_4
  69. return ColorTranslator.ToHtml(color);
  70. #else
  71. return String.Join(String.Empty, new String[] {
  72. "#",
  73. color.R.ToString("X2"),
  74. color.G.ToString("X2"),
  75. color.B.ToString("X2")
  76. });
  77. #endif
  78. }
  79. private static bool CheckNewHandlerInLocationTags(XmlNode element)
  80. {
  81. foreach (XmlNode locationNode in element.SelectNodes("location"))
  82. if (CheckNewHandler(locationNode))
  83. return true;
  84. return false;
  85. }
  86. private static bool CheckNewHandler(XmlNode element)
  87. {
  88. bool found = false;
  89. XmlNode node = element.SelectSingleNode("system.webServer");
  90. if (node != null)
  91. {
  92. XmlNode node2 = node.SelectSingleNode("handlers");
  93. if (node2 != null)
  94. {
  95. XmlNode node3 = node2.SelectSingleNode(String.Format("add[@path=\"{0}\"]", HandlerFileName));
  96. found = (node3 != null);
  97. }
  98. }
  99. return found;
  100. }
  101. private static bool CheckOldHandler(XmlNode element)
  102. {
  103. bool found = false;
  104. XmlNode node = element.SelectSingleNode("system.web");
  105. if (node != null)
  106. {
  107. XmlNode node2 = node.SelectSingleNode("httpHandlers");
  108. if (node2 != null)
  109. {
  110. XmlNode node3 = node2.SelectSingleNode(String.Format("add[@path=\"{0}\"]", HandlerFileName));
  111. found = (node3 != null);
  112. }
  113. }
  114. return found;
  115. }
  116. /// <summary>
  117. /// Check http handlers in web.config
  118. /// </summary>
  119. /// <returns></returns>
  120. public static bool CheckHandlers()
  121. {
  122. string webConfigFile = HttpContext.Current.Server.MapPath("~/web.config");
  123. if (!File.Exists(webConfigFile))
  124. webConfigFile = HttpContext.Current.Server.MapPath("~/Web.config");
  125. bool found1 = false;
  126. bool found2 = false;
  127. bool found3 = false;
  128. if (File.Exists(webConfigFile))
  129. {
  130. XmlDocument xml = new XmlDocument();
  131. xml.Load(webConfigFile);
  132. XmlElement element = xml.DocumentElement;
  133. found1 = CheckOldHandler(element);
  134. found2 = CheckNewHandler(element);
  135. found3 = CheckNewHandlerInLocationTags(element);
  136. }
  137. return found1 || found2 || found3;
  138. }
  139. /// <summary>
  140. /// Add http handlers in web.config
  141. /// </summary>
  142. public static void AddHandlers(string webConfigFile)
  143. {
  144. if (File.Exists(webConfigFile))
  145. {
  146. bool modified = false;
  147. XmlDocument xml = new XmlDocument();
  148. xml.Load(webConfigFile);
  149. XmlElement element = xml.DocumentElement;
  150. // integrated style
  151. string s = "system.webServer";
  152. XmlNode node = element.SelectSingleNode(s);
  153. if (node == null)
  154. {
  155. node = xml.CreateElement(s);
  156. element.AppendChild(node);
  157. }
  158. XmlNode node2 = node.SelectSingleNode("validation[@validateIntegratedModeConfiguration=\"false\"]");
  159. if (node2 == null)
  160. {
  161. node2 = xml.CreateElement("validation");
  162. XmlAttribute a = xml.CreateAttribute("validateIntegratedModeConfiguration");
  163. a.Value = "false";
  164. node2.Attributes.Append(a);
  165. node.AppendChild(node2);
  166. modified = true;
  167. }
  168. s = "handlers";
  169. node2 = node.SelectSingleNode(s);
  170. if (node2 == null)
  171. {
  172. node2 = xml.CreateElement(s);
  173. node.AppendChild(node2);
  174. }
  175. XmlNode node3 = node2.SelectSingleNode(String.Format("add[@path=\"{0}\"]", HandlerFileName));
  176. if (node3 == null)
  177. {
  178. node3 = xml.CreateElement("add");
  179. XmlAttribute a = xml.CreateAttribute("name");
  180. a.Value = "FastReportHandler";
  181. node3.Attributes.Append(a);
  182. a = xml.CreateAttribute("path");
  183. a.Value = HandlerFileName;
  184. node3.Attributes.Append(a);
  185. a = xml.CreateAttribute("verb");
  186. a.Value = "*";
  187. node3.Attributes.Append(a);
  188. a = xml.CreateAttribute("type");
  189. a.Value = "FastReport.Web.Handlers.WebExport";
  190. node3.Attributes.Append(a);
  191. node2.AppendChild(node3);
  192. modified = true;
  193. }
  194. // standard style
  195. s = "system.web";
  196. node = element.SelectSingleNode(s);
  197. if (node == null)
  198. {
  199. node = xml.CreateElement(s);
  200. element.AppendChild(node);
  201. }
  202. s = "httpHandlers";
  203. node2 = node.SelectSingleNode(s);
  204. if (node2 == null)
  205. {
  206. node2 = xml.CreateElement(s);
  207. node.AppendChild(node2);
  208. }
  209. node3 = node2.SelectSingleNode(String.Format("add[@path=\"{0}\"]", HandlerFileName));
  210. if (node3 == null)
  211. {
  212. node3 = xml.CreateElement("add");
  213. XmlAttribute a = xml.CreateAttribute("path");
  214. a.Value = HandlerFileName;
  215. node3.Attributes.Append(a);
  216. a = xml.CreateAttribute("verb");
  217. a.Value = "*";
  218. node3.Attributes.Append(a);
  219. a = xml.CreateAttribute("type");
  220. a.Value = "FastReport.Web.Handlers.WebExport";
  221. node3.Attributes.Append(a);
  222. node2.AppendChild(node3);
  223. modified = true;
  224. }
  225. // save config
  226. if (modified)
  227. xml.Save(webConfigFile);
  228. }
  229. }
  230. /// <summary>
  231. ///
  232. /// </summary>
  233. public static void CheckHandlersRuntime()
  234. {
  235. if (!CheckHandlers())
  236. throw new Exception(GetHandlerError());
  237. }
  238. /// <summary>
  239. ///
  240. /// </summary>
  241. /// <returns></returns>
  242. public static string GetHandlerError()
  243. {
  244. StringBuilder e = new StringBuilder();
  245. e.AppendLine("FastReport handler not found or its extension has been changed . Please check your web.config:");
  246. e.AppendLine("IIS6");
  247. e.AppendLine("<system.web>");
  248. e.AppendLine("...");
  249. e.AppendLine(" <httpHandlers>");
  250. e.Append(" <add path=\"").Append(HandlerFileName).AppendLine("\" verb=\"*\" type=\"FastReport.Web.Handlers.WebExport\"/>");
  251. e.AppendLine(" ....");
  252. e.AppendLine(" </httpHandlers>");
  253. e.AppendLine("</system.web>");
  254. e.AppendLine("IIS7");
  255. e.AppendLine("<configuration>");
  256. e.AppendLine("...");
  257. e.AppendLine(" <system.webServer>");
  258. e.AppendLine(" <validation validateIntegratedModeConfiguration=\"false\"/>");
  259. e.AppendLine("...");
  260. e.AppendLine(" <handlers>");
  261. e.AppendLine(" ...");
  262. e.AppendLine(" <remove name=\"FastReportHandler\"/>");
  263. e.Append(" <add name=\"FastReportHandler\" path=\"").Append(HandlerFileName).AppendLine("\" verb=\"*\" type=\"FastReport.Web.Handlers.WebExport\" />");
  264. e.AppendLine(" </handlers>");
  265. e.AppendLine(" </system.webServer>");
  266. e.AppendLine("</configuration>");
  267. return e.ToString();
  268. }
  269. /// <summary>
  270. ///
  271. /// </summary>
  272. /// <param name="str"></param>
  273. /// <returns></returns>
  274. public static string ReverseString(string str)
  275. {
  276. StringBuilder result = new StringBuilder(str.Length);
  277. int i, j;
  278. if (!String.IsNullOrEmpty(str))
  279. for (j = 0, i = str.Length - 1; i >= 0; i--, j++)
  280. result.Append(str[i]);
  281. return result.ToString();
  282. }
  283. /// <summary>
  284. ///
  285. /// </summary>
  286. /// <param name="context"></param>
  287. /// <param name="id"></param>
  288. /// <returns></returns>
  289. public static string GetGUID(HttpContext context, string id)
  290. {
  291. string result = String.Empty;
  292. if (HttpContext.Current != null)
  293. result = context.Request[String.Concat(id, "$", WebUtils.HiddenIDSuffix)];
  294. if (String.IsNullOrEmpty(result))
  295. result = Guid.NewGuid().ToString().Replace("-", "");
  296. else
  297. result = WebUtils.ReverseString(result);
  298. return result;
  299. }
  300. /// <summary>
  301. ///
  302. /// </summary>
  303. /// <returns></returns>
  304. public static string GetGUID()
  305. {
  306. Guid guid = Guid.Empty;
  307. while (Guid.Empty == guid)
  308. {
  309. guid = Guid.NewGuid();
  310. }
  311. string guidStr = String.Concat("fr",
  312. Convert.ToBase64String(guid.ToByteArray()).Substring(0, 22).Replace("/", "_").Replace("+", "-"));
  313. return guidStr;
  314. }
  315. /// <summary>
  316. /// IE8 and older browsers detection.
  317. /// </summary>
  318. /// <param name="context"></param>
  319. /// <returns></returns>
  320. public static bool IsIE8(HttpContext context)
  321. {
  322. if (context != null)
  323. return (context.Request.Browser.Browser == "InternetExplorer" ||
  324. context.Request.Browser.Browser == "IE")
  325. && (context.Request.Browser.Version == "8.0" ||
  326. context.Request.Browser.Version == "7.0" ||
  327. context.Request.Browser.Version == "6.0");
  328. else
  329. return false;
  330. }
  331. /// <summary>
  332. /// Add NoCache haders in Context.Reponse
  333. /// </summary>
  334. /// <param name="context"></param>
  335. public static void AddNoCacheHeaders(HttpContext context)
  336. {
  337. context.Response.AddHeader("Expires", "May, 3 Jul 1997 05:00:00 GMT");
  338. context.Response.AddHeader("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0");
  339. context.Response.AddHeader("Pragma", "no-cache");
  340. }
  341. /*/// <summary>
  342. /// Setup the context.
  343. /// </summary>
  344. /// <param name="context"></param>
  345. //public static void SetContext(HttpContext context)
  346. //{
  347. // SetAzureCookies(context);
  348. // AddNoCacheHeaders(context);
  349. //} */
  350. /// <summary>
  351. /// Converts Color in HTML format with transparency.
  352. /// </summary>
  353. /// <param name="color"></param>
  354. /// <returns></returns>
  355. public static string RGBAColor(Color color)
  356. {
  357. NumberFormatInfo provider = new NumberFormatInfo();
  358. provider.NumberGroupSeparator = String.Empty;
  359. provider.NumberDecimalSeparator = ".";
  360. return String.Format("rgba({0}, {1}, {2}, {3})",
  361. color.R.ToString(""),
  362. color.G.ToString(""),
  363. color.B.ToString(""),
  364. Math.Round((float)color.A / 255).ToString(provider)
  365. );
  366. }
  367. internal static void Write(Stream stream, string value)
  368. {
  369. byte[] buf = Encoding.UTF8.GetBytes(value);
  370. stream.Write(buf, 0, buf.Length);
  371. }
  372. internal static void ResponseChunked(HttpResponse httpResponse, byte[] p)
  373. {
  374. int chunkSize = 2048;
  375. int position = 0;
  376. while (position < p.Length && httpResponse.IsClientConnected)
  377. {
  378. if (chunkSize > p.Length - position)
  379. chunkSize = p.Length - position;
  380. httpResponse.OutputStream.Write(p, position, chunkSize);
  381. position += chunkSize;
  382. httpResponse.Flush();
  383. }
  384. }
  385. internal static string GetAppRoot(HttpContext context, string path)
  386. {
  387. if (path.IndexOf("://") != -1)
  388. return path;
  389. string s = String.Concat(context.Request.ApplicationPath == "/" ? "" : context.Request.ApplicationPath, path.IndexOf("/") == 0 ? "" : "/", path.Replace("~/", ""));
  390. return s;
  391. }
  392. internal static object GetSalt()
  393. {
  394. return string.Concat("&s=", new Random(DateTime.Now.Millisecond).Next(10000).ToString());
  395. }
  396. internal static string GetBasePath(HttpContext httpContext)
  397. {
  398. if (httpContext != null)
  399. {
  400. string s = httpContext.Request.ApplicationPath;
  401. if (s.EndsWith("/"))
  402. return s;
  403. else
  404. return s + "/";
  405. }
  406. else
  407. return string.Empty;
  408. }
  409. internal static bool SetupResponse(WebReport webReport, HttpContext context)
  410. {
  411. if (webReport != null)
  412. {
  413. CustomAuthEventArgs authArgs = new CustomAuthEventArgs();
  414. authArgs.Context = context;
  415. webReport.OnCustomAuth(authArgs);
  416. if (!authArgs.AuthPassed)
  417. {
  418. context.Response.StatusCode = 401;
  419. return false;
  420. }
  421. if (webReport.ResponseHeaders != null)
  422. {
  423. foreach (string key in webReport.ResponseHeaders.AllKeys)
  424. context.Response.Headers.Add(key, webReport.ResponseHeaders.Get(key));
  425. }
  426. }
  427. WebUtils.SetAzureCookies(context);
  428. WebUtils.AddNoCacheHeaders(context);
  429. return true;
  430. }
  431. internal static void SetAzureCookies(HttpContext context)
  432. {
  433. string ARRAffinity = GetWebsiteInstanceId();
  434. if (!String.IsNullOrEmpty(ARRAffinity))
  435. {
  436. HttpCookie cookie = new HttpCookie("ARRAffinity", ARRAffinity);
  437. cookie.Expires = DateTime.Now.AddMinutes(30);
  438. context.Response.Cookies.Add(cookie);
  439. }
  440. }
  441. internal static void CopyCookies(HttpWebRequest request, HttpContext context)
  442. {
  443. if (HttpContext.Current == null)
  444. return;
  445. if (request.CookieContainer == null)
  446. request.CookieContainer = new CookieContainer();
  447. foreach (var cookieKey in HttpContext.Current.Request.Cookies.Keys)
  448. {
  449. if (!cookieKey.ToString().Equals("ASP.NET_SessionId"))
  450. {
  451. var cookie = HttpContext.Current.Request.Cookies[cookieKey.ToString()];
  452. request.CookieContainer.Add(new Cookie(cookie.Name, cookie.Value, cookie.Path, string.IsNullOrEmpty(cookie.Domain)
  453. ? HttpContext.Current.Request.Url.Host
  454. : cookie.Domain));
  455. }
  456. }
  457. UriBuilder uri = new UriBuilder
  458. {
  459. Scheme = context.Request.Url.Scheme,
  460. Host = context.Request.Url.Host
  461. };
  462. string ARRAffinity = GetWebsiteInstanceId();
  463. if (!String.IsNullOrEmpty(ARRAffinity))
  464. request.CookieContainer.Add(uri.Uri, new Cookie("ARRAffinity", ARRAffinity));
  465. }
  466. internal static string GetARRAffinity()
  467. {
  468. string id = GetWebsiteInstanceId();
  469. if (!String.IsNullOrEmpty(id))
  470. return String.Concat("&ARRAffinity=", id);
  471. else
  472. return String.Empty;
  473. }
  474. internal static string GetWebsiteInstanceId()
  475. {
  476. return Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID");
  477. }
  478. internal static string JavaScriptStringEncode(string s)
  479. {
  480. if (string.IsNullOrEmpty(s))
  481. return string.Empty;
  482. bool needEncode = false;
  483. for (int i = 0; i < s.Length; i++)
  484. {
  485. char c = s[i];
  486. if (c >= 0 && c <= 31 || c == 34 || c == 39 || c == 60 || c == 62 || c == 92)
  487. {
  488. needEncode = true;
  489. break;
  490. }
  491. }
  492. if (!needEncode)
  493. return s;
  494. StringBuilder sb = new StringBuilder();
  495. for (int i = 0; i < s.Length; i++)
  496. {
  497. char c = s[i];
  498. if (c >= 0 && c <= 7 || c == 11 || c >= 14 && c <= 31 || c == 39 || c == 60 || c == 62)
  499. {
  500. sb.AppendFormat("\\u{0:x4}", (int)c);
  501. }
  502. else
  503. {
  504. switch ((int)c)
  505. {
  506. case 8:
  507. sb.Append("\\b");
  508. break;
  509. case 9:
  510. sb.Append("\\t");
  511. break;
  512. case 10:
  513. sb.Append("\\n");
  514. break;
  515. case 12:
  516. sb.Append("\\f");
  517. break;
  518. case 13:
  519. sb.Append("\\r");
  520. break;
  521. case 34:
  522. sb.Append("\\\"");
  523. break;
  524. case 92:
  525. sb.Append("\\\\");
  526. break;
  527. default:
  528. sb.Append(c);
  529. break;
  530. }
  531. }
  532. }
  533. return sb.ToString();
  534. }
  535. internal static bool IsPng(byte[] image)
  536. {
  537. byte[] pngHeader = new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 };
  538. bool isPng = true;
  539. for (int i = 0; i < 8; i++)
  540. if (image[i] != pngHeader[i])
  541. {
  542. isPng = false;
  543. break;
  544. }
  545. return isPng;
  546. }
  547. }
  548. }