PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/stable-1.2.0/Server/PHPService.cs

#
C# | 471 lines | 398 code | 65 blank | 8 comment | 27 complexity | 2474b9448efba6c7676d9dbd93be2d37 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. //-----------------------------------------------------------------------
  2. // <copyright>
  3. // Copyright (C) Ruslan Yakushev for the PHP Manager for IIS project.
  4. //
  5. // This file is subject to the terms and conditions of the Microsoft Public License (MS-PL).
  6. // See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL for more details.
  7. // </copyright>
  8. //-----------------------------------------------------------------------
  9. using System;
  10. using System.Collections;
  11. using System.Diagnostics;
  12. using System.IO;
  13. using Microsoft.Web.Administration;
  14. using Microsoft.Web.Management.Server;
  15. using Web.Management.PHP.Config;
  16. using Web.Management.PHP.Handlers;
  17. namespace Web.Management.PHP
  18. {
  19. internal sealed class PHPService : ModuleService
  20. {
  21. #if DEBUG
  22. private const bool Passthrough = false;
  23. #else
  24. private const bool Passthrough = true;
  25. #endif
  26. [ModuleServiceMethod(PassThrough = Passthrough)]
  27. public string AddExtension(string extensionPath)
  28. {
  29. EnsureServerConnection();
  30. string result = null;
  31. try
  32. {
  33. ManagementUnitWrapper mgmtUnitWrapper = new ManagementUnitWrapper(ManagementUnit);
  34. PHPConfigHelper configHelper = new PHPConfigHelper(mgmtUnitWrapper);
  35. result = configHelper.AddExtension(extensionPath);
  36. }
  37. catch (FileNotFoundException)
  38. {
  39. RaiseException("ErrorPHPIniNotFound");
  40. }
  41. catch (IOException)
  42. {
  43. RaiseException("ErrorExtensionFileAlreadyExists");
  44. }
  45. catch (InvalidOperationException)
  46. {
  47. RaiseException("ErrorPHPIsNotRegistered");
  48. }
  49. catch (Exception)
  50. {
  51. RaiseException("ErrorCannotAddExtension");
  52. }
  53. return result;
  54. }
  55. [ModuleServiceMethod(PassThrough = Passthrough)]
  56. public void AddOrUpdateSettings(object settingsData)
  57. {
  58. EnsureServerConnection();
  59. RemoteObjectCollection<PHPIniSetting> settings = new RemoteObjectCollection<PHPIniSetting>();
  60. ((IRemoteObject)settings).SetData(settingsData);
  61. try
  62. {
  63. ManagementUnitWrapper mgmtUnitWrapper = new ManagementUnitWrapper(ManagementUnit);
  64. PHPConfigHelper configHelper = new PHPConfigHelper(mgmtUnitWrapper);
  65. configHelper.AddOrUpdatePHPIniSettings(settings);
  66. }
  67. catch (FileNotFoundException)
  68. {
  69. RaiseException("ErrorPHPIniNotFound");
  70. }
  71. catch (InvalidOperationException)
  72. {
  73. RaiseException("ErrorPHPIsNotRegistered");
  74. }
  75. }
  76. [ModuleServiceMethod(PassThrough = Passthrough)]
  77. public void ApplyRecommendedSettings(ArrayList configIssueIndexes)
  78. {
  79. EnsureServerConnection();
  80. try
  81. {
  82. ManagementUnitWrapper mgmtUnitWrapper = new ManagementUnitWrapper(ManagementUnit);
  83. PHPConfigHelper configHelper = new PHPConfigHelper(mgmtUnitWrapper);
  84. configHelper.ApplyRecommendedSettings(configIssueIndexes);
  85. }
  86. catch (FileNotFoundException)
  87. {
  88. RaiseException("ErrorPHPIniNotFound");
  89. }
  90. catch (InvalidOperationException)
  91. {
  92. RaiseException("ErrorPHPIsNotRegistered");
  93. }
  94. }
  95. [ModuleServiceMethod(PassThrough = Passthrough)]
  96. public bool CheckForLocalPHPHandler(string siteName, string virtualPath)
  97. {
  98. EnsureServerOrSiteConnection();
  99. if (String.IsNullOrEmpty(siteName))
  100. {
  101. throw new InvalidOperationException();
  102. }
  103. Site site = ManagementUnit.ReadOnlyServerManager.Sites[siteName];
  104. if (site == null)
  105. {
  106. throw new InvalidOperationException();
  107. }
  108. ServerManagerWrapper serverManagerWrapper = new ServerManagerWrapper(ManagementUnit.ReadOnlyServerManager, siteName, virtualPath);
  109. PHPConfigHelper configHelper = new PHPConfigHelper(serverManagerWrapper);
  110. PHPConfigInfo configInfo = configHelper.GetPHPConfigInfo();
  111. if (configInfo.RegistrationType != PHPRegistrationType.FastCgi)
  112. {
  113. throw new InvalidOperationException("PHP is not registered via FastCGI, hence there is no FastCGI handler defined");
  114. }
  115. return configInfo.HandlerIsLocal;
  116. }
  117. [ModuleServiceMethod(PassThrough = Passthrough)]
  118. public string CreatePHPInfo(string siteName)
  119. {
  120. EnsureServerOrSiteConnection();
  121. if (String.IsNullOrEmpty(siteName))
  122. {
  123. throw new InvalidOperationException();
  124. }
  125. Site site = ManagementUnit.ReadOnlyServerManager.Sites[siteName];
  126. if (site == null)
  127. {
  128. throw new InvalidOperationException();
  129. }
  130. string navigatorPath = siteName;
  131. if (ManagementUnit.ConfigurationPath.PathType != ConfigurationPathType.Server)
  132. {
  133. navigatorPath = ManagementUnit.ConfigurationPath.GetEffectiveConfigurationPath(ManagementUnit.Scope);
  134. }
  135. ManagementContentNavigator navigator = ManagementContentNavigator.Create(ManagementUnit);
  136. if (!navigator.MoveToPath(navigatorPath))
  137. {
  138. throw new InvalidOperationException();
  139. }
  140. string randomString = Path.GetRandomFileName();
  141. string fileName = String.Format("{0}.php", Path.GetFileNameWithoutExtension(randomString));
  142. string filePath = Path.Combine(Environment.ExpandEnvironmentVariables(navigator.PhysicalPath), fileName);
  143. try
  144. {
  145. File.WriteAllText(filePath, @"<?php phpinfo(); ?>");
  146. }
  147. catch (UnauthorizedAccessException)
  148. {
  149. RaiseException("ErrorCannotCreatePHPInfo");
  150. }
  151. return filePath;
  152. }
  153. private void EnsureServerConnection()
  154. {
  155. if (ManagementUnit.Scope != ManagementScope.Server)
  156. {
  157. throw new UnauthorizedAccessException();
  158. }
  159. }
  160. private void EnsureServerOrSiteConnection()
  161. {
  162. if (ManagementUnit.Scope != ManagementScope.Server && ManagementUnit.Scope != ManagementScope.Site)
  163. {
  164. throw new UnauthorizedAccessException();
  165. }
  166. }
  167. [ModuleServiceMethod(PassThrough = Passthrough)]
  168. public object GetAllPHPVersions()
  169. {
  170. EnsureServerOrSiteConnection();
  171. RemoteObjectCollection<PHPVersion> versions = null;
  172. try
  173. {
  174. ManagementUnitWrapper mgmtUnitWrapper = new ManagementUnitWrapper(ManagementUnit);
  175. PHPConfigHelper configHelper = new PHPConfigHelper(mgmtUnitWrapper);
  176. versions = configHelper.GetAllPHPVersions();
  177. }
  178. catch (FileNotFoundException)
  179. {
  180. RaiseException("ErrorPHPIniNotFound");
  181. }
  182. catch (InvalidOperationException)
  183. {
  184. RaiseException("ErrorPHPIsNotRegistered");
  185. }
  186. return (versions != null) ? versions.GetData() : null;
  187. }
  188. [ModuleServiceMethod(PassThrough = Passthrough)]
  189. public object GetConfigIssues()
  190. {
  191. RemoteObjectCollection<PHPConfigIssue> configIssues = null;
  192. try
  193. {
  194. ManagementUnitWrapper mgmtUnitWrapper = new ManagementUnitWrapper(ManagementUnit);
  195. PHPConfigHelper configHelper = new PHPConfigHelper(mgmtUnitWrapper);
  196. configIssues = configHelper.ValidateConfiguration();
  197. }
  198. catch (FileNotFoundException)
  199. {
  200. RaiseException("ErrorPHPIniNotFound");
  201. }
  202. catch (InvalidOperationException)
  203. {
  204. RaiseException("ErrorPHPIsNotRegistered");
  205. }
  206. return (configIssues != null) ? configIssues.GetData() : null;
  207. }
  208. [ModuleServiceMethod(PassThrough = Passthrough)]
  209. public object GetPHPConfigInfo()
  210. {
  211. EnsureServerOrSiteConnection();
  212. PHPConfigInfo result = null;
  213. try
  214. {
  215. ManagementUnitWrapper mgmtUnitWrapper = new ManagementUnitWrapper(ManagementUnit);
  216. PHPConfigHelper configHelper = new PHPConfigHelper(mgmtUnitWrapper);
  217. result = configHelper.GetPHPConfigInfo();
  218. }
  219. catch (FileNotFoundException)
  220. {
  221. RaiseException("ErrorPHPIniNotFound");
  222. }
  223. catch (InvalidOperationException)
  224. {
  225. RaiseException("ErrorPHPIsNotRegistered");
  226. }
  227. return (result != null) ? result.GetData() : null;
  228. }
  229. [ModuleServiceMethod(PassThrough = Passthrough)]
  230. public object GetPHPIniPhysicalPath()
  231. {
  232. if (!ManagementUnit.Context.IsLocalConnection)
  233. {
  234. return null;
  235. }
  236. string phpiniPath = null;
  237. try
  238. {
  239. ManagementUnitWrapper mgmtUnitWrapper = new ManagementUnitWrapper(ManagementUnit);
  240. PHPConfigHelper configHelper = new PHPConfigHelper(mgmtUnitWrapper);
  241. phpiniPath = configHelper.PHPIniFilePath;
  242. }
  243. catch(FileNotFoundException)
  244. {
  245. RaiseException("ErrorPHPIniNotFound");
  246. }
  247. return phpiniPath;
  248. }
  249. [ModuleServiceMethod(PassThrough = Passthrough)]
  250. public object GetPHPIniSettings()
  251. {
  252. EnsureServerOrSiteConnection();
  253. PHPIniFile file = null;
  254. try
  255. {
  256. ManagementUnitWrapper mgmtUnitWrapper = new ManagementUnitWrapper(ManagementUnit);
  257. PHPConfigHelper configHelper = new PHPConfigHelper(mgmtUnitWrapper);
  258. file = configHelper.GetPHPIniFile();
  259. }
  260. catch (FileNotFoundException)
  261. {
  262. RaiseException("ErrorPHPIniNotFound");
  263. }
  264. catch (InvalidOperationException)
  265. {
  266. RaiseException("ErrorPHPIsNotRegistered");
  267. }
  268. Debug.Assert(file != null);
  269. return file.GetData();
  270. }
  271. [ModuleServiceMethod(PassThrough = Passthrough)]
  272. public ArrayList GetSiteBindings(string siteName)
  273. {
  274. EnsureServerOrSiteConnection();
  275. if (String.IsNullOrEmpty(siteName))
  276. {
  277. throw new InvalidOperationException();
  278. }
  279. Site site = ManagementUnit.ReadOnlyServerManager.Sites[siteName];
  280. if (site == null)
  281. {
  282. throw new InvalidOperationException();
  283. }
  284. ArrayList list = new ArrayList();
  285. foreach (Binding binding in site.Bindings)
  286. {
  287. string protocol = binding.Protocol;
  288. if (String.Equals(protocol, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase) ||
  289. String.Equals(protocol, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
  290. {
  291. list.Add(new string[] { protocol, binding.BindingInformation });
  292. }
  293. }
  294. return list;
  295. }
  296. [ModuleServiceMethod(PassThrough = Passthrough)]
  297. public ArrayList GetSites()
  298. {
  299. EnsureServerConnection();
  300. SiteCollection siteCollection = ManagementUnit.ReadOnlyServerManager.Sites;
  301. ArrayList sites = new ArrayList(siteCollection.Count);
  302. foreach (Site site in siteCollection)
  303. {
  304. sites.Add(site.Name);
  305. }
  306. return sites;
  307. }
  308. [ModuleServiceMethod(PassThrough = Passthrough)]
  309. public void RegisterPHPWithIIS(string phpExePath)
  310. {
  311. EnsureServerConnection();
  312. try
  313. {
  314. ManagementUnitWrapper mgmtUnitWrapper = new ManagementUnitWrapper(ManagementUnit);
  315. PHPConfigHelper configHelper = new PHPConfigHelper(mgmtUnitWrapper);
  316. configHelper.RegisterPHPWithIIS(phpExePath);
  317. }
  318. catch (ArgumentException)
  319. {
  320. RaiseException("ErrorInvalidPHPExecutablePath");
  321. }
  322. catch (FileNotFoundException)
  323. {
  324. RaiseException("ErrorNoPHPFilesInDirectory");
  325. }
  326. catch (DirectoryNotFoundException)
  327. {
  328. RaiseException("ErrorNoExtDirectory");
  329. }
  330. }
  331. [ModuleServiceMethod(PassThrough = Passthrough)]
  332. public void RemovePHPInfo(string filePath)
  333. {
  334. EnsureServerOrSiteConnection();
  335. if (!File.Exists(filePath)) {
  336. return;
  337. }
  338. File.Delete(filePath);
  339. }
  340. [ModuleServiceMethod(PassThrough = Passthrough)]
  341. public void RemovePHPIniSetting(object settingData)
  342. {
  343. EnsureServerConnection();
  344. PHPIniSetting setting = new PHPIniSetting();
  345. setting.SetData(settingData);
  346. try
  347. {
  348. ManagementUnitWrapper mgmtUnitWrapper = new ManagementUnitWrapper(ManagementUnit);
  349. PHPConfigHelper configHelper = new PHPConfigHelper(mgmtUnitWrapper);
  350. configHelper.RemovePHPIniSetting(setting);
  351. }
  352. catch (FileNotFoundException)
  353. {
  354. RaiseException("ErrorPHPIniNotFound");
  355. }
  356. catch (InvalidOperationException)
  357. {
  358. RaiseException("ErrorPHPIsNotRegistered");
  359. }
  360. }
  361. [ModuleServiceMethod(PassThrough = Passthrough)]
  362. public void SelectPHPVersion(string name)
  363. {
  364. EnsureServerOrSiteConnection();
  365. try
  366. {
  367. ManagementUnitWrapper mgmtUnitWrapper = new ManagementUnitWrapper(ManagementUnit);
  368. PHPConfigHelper configHelper = new PHPConfigHelper(mgmtUnitWrapper);
  369. configHelper.SelectPHPHandler(name);
  370. }
  371. catch (FileLoadException)
  372. {
  373. RaiseException("ErrorSomeHandlersLocked");
  374. }
  375. catch (FileNotFoundException)
  376. {
  377. RaiseException("ErrorPHPIniNotFound");
  378. }
  379. catch (InvalidOperationException)
  380. {
  381. RaiseException("ErrorPHPIsNotRegistered");
  382. }
  383. }
  384. [ModuleServiceMethod(PassThrough = Passthrough)]
  385. public void UpdateExtensions(object extensionsData)
  386. {
  387. EnsureServerConnection();
  388. RemoteObjectCollection<PHPIniExtension> extensions = new RemoteObjectCollection<PHPIniExtension>();
  389. ((IRemoteObject)extensions).SetData(extensionsData);
  390. try
  391. {
  392. ManagementUnitWrapper mgmtUnitWrapper = new ManagementUnitWrapper(ManagementUnit);
  393. PHPConfigHelper configHelper = new PHPConfigHelper(mgmtUnitWrapper);
  394. configHelper.UpdateExtensions(extensions);
  395. }
  396. catch (FileNotFoundException)
  397. {
  398. RaiseException("ErrorPHPIniNotFound");
  399. }
  400. catch (InvalidOperationException)
  401. {
  402. RaiseException("ErrorPHPIsNotRegistered");
  403. }
  404. }
  405. }
  406. }