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