2 // SvcHttpHandlerFactory.cs
5 // Ankit Jain <jankit@novell.com>
6 // Atsushi Enomoto <atsushi@ximian.com>
8 // Copyright (C) 2006,2009 Novell, Inc. http://www.novell.com
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System
.Collections
;
32 using System
.Collections
.Generic
;
33 using System
.Collections
.Specialized
;
36 using System
.Reflection
;
37 using System
.ServiceModel
;
39 using System
.Web
.Caching
;
40 using System
.Web
.Compilation
;
42 namespace System
.ServiceModel
.Channels
{
44 internal class SvcHttpHandlerFactory
: IHttpHandlerFactory
46 static Dictionary
<string, SvcHttpHandler
> handlers
= new Dictionary
<string, SvcHttpHandler
> ();
47 string privateBinPath
;
48 Type service_type
, factory_type
;
50 public SvcHttpHandlerFactory ()
52 ServiceHostingEnvironment
.InAspNet
= true;
55 public static SvcHttpHandler
GetHandlerForListener (IChannelListener listener
)
57 return handlers
.Values
.First (h
=> h
.Host
.ChannelDispatchers
.Any (cd
=> cd
.Listener
== listener
));
60 public IHttpHandler
GetHandler (HttpContext context
, string requestType
, string url
, string pathTranslated
)
64 if (handlers
.ContainsKey (url
))
65 return handlers
[url
];
67 LoadTypeFromSvc (pathTranslated
, url
, context
);
68 if (service_type
== null)
69 throw new Exception (String
.Format (
70 "Could not find service for url : '{0}'", url
));
72 SvcHttpHandler handler
= new SvcHttpHandler (service_type
, factory_type
, url
);
73 handlers
[url
] = handler
;
80 public void ReleaseHandler (IHttpHandler handler
)
85 void LoadTypeFromSvc (string path
, string url
, HttpContext context
)
87 if (CachingCompiler
.GetTypeFromCache (path
) != null)
90 ServiceHostParser parser
= new ServiceHostParser (path
, url
, context
);
93 if (parser
.Program
== null) {
94 //FIXME: Not caching, as parser.TypeName could be
95 //just typename or fully qualified name
96 service_type
= GetTypeFromBinAndConfig (parser
.TypeName
);
97 /*CachingCompiler.InsertType (
98 service_type, service_type.Assembly.Location, url,
99 new CacheItemRemovedCallback (RemovedCallback));*/
101 service_type
= CachingCompiler
.CompileAndGetType (
103 new CacheItemRemovedCallback (RemovedCallback
));
106 if (parser
.Factory
!= null) {
107 factory_type
= GetTypeFromBinAndConfig (parser
.Factory
);
108 /*CachingCompiler.InsertType (
109 factory_type, factory_type.Assembly.Location, url,
110 new CacheItemRemovedCallback (RemovedCallback));*/
114 string PrivateBinPath
{
116 if (privateBinPath
!= null)
117 return privateBinPath
;
119 AppDomainSetup setup
= AppDomain
.CurrentDomain
.SetupInformation
;
120 privateBinPath
= setup
.PrivateBinPath
;
122 if (!Path
.IsPathRooted (privateBinPath
)) {
123 string appbase
= setup
.ApplicationBase
;
124 if (appbase
.StartsWith ("file://")) {
125 appbase
= appbase
.Substring (7);
126 if (Path
.DirectorySeparatorChar
!= '/')
127 appbase
= appbase
.Replace ('/', Path
.DirectorySeparatorChar
);
129 privateBinPath
= Path
.Combine (appbase
, privateBinPath
);
132 return privateBinPath
;
136 Type
GetTypeFromBinAndConfig (string typeName
)
138 string assname
= null;
139 int idx
= typeName
.IndexOf (',');
141 assname
= typeName
.Substring (idx
+ 1).Trim ();
142 typeName
= typeName
.Substring (0, idx
);
146 foreach (Assembly ass
in BuildManager
.GetReferencedAssemblies ()) {
147 if (assname
!= null && ass
.GetName ().Name
!= assname
)
149 Type type
= ass
.GetType (typeName
, false);
152 throw new HttpException (String
.Format ("Type {0} is not unique.", typeName
));
158 throw new HttpException (String
.Format ("Type {0} not found.", typeName
));
163 public static void RemovedCallback (string key
, object value, CacheItemRemovedReason reason
)
165 if (key
.StartsWith (CachingCompiler
.cacheTypePrefix
)) {
166 string path
= key
.Remove (0, CachingCompiler
.cacheTypePrefix
.Length
);
168 SvcHttpHandler handler
;
169 if (!handlers
.TryGetValue (path
, out handler
))
173 handlers
.Remove (path
);