public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack,
IMessage requestMsg,
ITransportHeaders requestHeaders, Stream requestStream,
out IMessage responseMsg, out ITransportHeaders responseHeaders,
out Stream responseStream)
{
if (requestMsg != null)
{
// The message has already been deserialized so delegate to the next sink.
return _nextSink.ProcessMessage(
sinkStack,
requestMsg, requestHeaders, requestStream,
out responseMsg, out responseHeaders, out responseStream);
}
if (requestHeaders == null)
throw new ArgumentNullException("requestHeaders");
BaseTransportHeaders wkRequestHeaders = requestHeaders as BaseTransportHeaders;
ServerProcessing processing;
responseHeaders = null;
responseStream = null;
String verb = null;
String contentType = null;
bool bCanServiceRequest = true;
// determine the content type
String contentTypeHeader = null;
if (wkRequestHeaders != null)
contentTypeHeader = wkRequestHeaders.ContentType;
else
contentTypeHeader = requestHeaders["Content-Type"] as String;
if (contentTypeHeader != null)
{
String charsetValue;
HttpChannelHelper.ParseContentType(contentTypeHeader,
out contentType, out charsetValue);
}
// check to see if Content-Type matches
if ((contentType != null) &&
(String.CompareOrdinal(contentType, CoreChannel.BinaryMimeType) != 0))
{
bCanServiceRequest = false;
}
// check for http specific verbs
if (_protocol == Protocol.Http)
{
verb = (String)requestHeaders["__RequestVerb"];
if (!verb.Equals("POST") && !verb.Equals("M-POST"))
bCanServiceRequest = false;
}
// either delegate or return an error message if we can't service the request
if (!bCanServiceRequest)
{
// delegate to next sink if available
if (_nextSink != null)
{
return _nextSink.ProcessMessage(sinkStack, null, requestHeaders, requestStream,
out responseMsg, out responseHeaders, out responseStream);
}
else
{
// send back an error message
if (_protocol == Protocol.Http)
{
// return a client bad request error
responseHeaders = new TransportHeaders();
responseHeaders["__HttpStatusCode"] = "400";
responseHeaders["__HttpReasonPhrase"] = "Bad Request";
responseStream = null;
responseMsg = null;
return ServerProcessing.Complete;
}
else
{
// The transport sink will catch this and do something here.
throw new RemotingException(
CoreChannel.GetResourceString("Remoting_Channels_InvalidRequestFormat"));
}
}
}
try
{
String objectUri = null;
bool bIsCustomErrorEnabled = true;
object oIsCustomErrorEnabled = requestHeaders["__CustomErrorsEnabled"];
if (oIsCustomErrorEnabled != null && oIsCustomErrorEnabled is bool){
bIsCustomErrorEnabled = (bool)oIsCustomErrorEnabled;
}
CallContext.SetData("__CustomErrorsEnabled", bIsCustomErrorEnabled);
if (wkRequestHeaders != null)
objectUri = wkRequestHeaders.RequestUri;
else
objectUri = (String)requestHeaders[CommonTransportKeys.RequestUri];
if (objectUri != lastUri && RemotingServices.GetServerTypeForUri(objectUri) == null)
throw new RemotingException(
CoreChannel.GetResourceString("Remoting_ChnlSink_UriNotPublished"));
else
lastUri = objectUri;
PermissionSet currentPermissionSet = null;
if (this.TypeFilterLevel != TypeFilterLevel.Full) {
currentPermissionSet = new PermissionSet(PermissionState.None);
currentPermissionSet.SetPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter));
}
try {
if (currentPermissionSet != null)
currentPermissionSet.PermitOnly();
// Deserialize Request - Stream to IMessage
requestMsg = CoreChannel.DeserializeBinaryRequestMessage(objectUri, requestStream, _strictBinding, this.TypeFilterLevel);
}
finally {
if (currentPermissionSet != null)
CodeAccessPermission.RevertPermitOnly();
}
requestStream.Close();
if(requestMsg == null)
{
throw new RemotingException(CoreChannel.GetResourceString("Remoting_DeserializeMessage"));
}
// Dispatch Call
sinkStack.Push(this, null);
processing =
_nextSink.ProcessMessage(sinkStack, requestMsg, requestHeaders, null,
out responseMsg, out responseHeaders, out responseStream);
// make sure that responseStream is null
if (responseStream != null)
{
throw new RemotingException(
CoreChannel.GetResourceString("Remoting_ChnlSink_WantNullResponseStream"));
}
switch (processing)
{
case ServerProcessing.Complete:
{
if (responseMsg == null)
throw new RemotingException(CoreChannel.GetResourceString("Remoting_DispatchMessage"));
sinkStack.Pop(this);
SerializeResponse(sinkStack, responseMsg,
ref responseHeaders, out responseStream);
break;
} // case ServerProcessing.Complete
case ServerProcessing.OneWay:
{
sinkStack.Pop(this);
break;
} // case ServerProcessing.OneWay:
case ServerProcessing.Async:
{
sinkStack.Store(this, null);
break;
} // case ServerProcessing.Async
} // switch (processing)
}
catch(Exception e)
{
processing = ServerProcessing.Complete;
responseMsg = new ReturnMessage(e, (IMethodCallMessage)(requestMsg==null?new ErrorMessage():requestMsg));
//TODO, sowmys: See if we could call SerializeResponse here
//We always set __ClientIsClr here since interop is not an issue
CallContext.SetData("__ClientIsClr", true);
responseStream = (MemoryStream)CoreChannel.SerializeBinaryMessage(responseMsg, _includeVersioning);
CallContext.FreeNamedDataSlot("__ClientIsClr");
responseStream.Position = 0;
responseHeaders = new TransportHeaders();
if (_protocol == Protocol.Http)
{
responseHeaders["Content-Type"] = CoreChannel.BinaryMimeType;
}
}
catch {
processing = ServerProcessing.Complete;
responseMsg = new ReturnMessage(new Exception(CoreChannel.GetResourceString("Remoting_nonClsCompliantException")), (IMethodCallMessage)(requestMsg==null?new ErrorMessage():requestMsg));
//TODO, sowmys: See if we could call SerializeResponse here
//We always set __ClientIsClr here since interop is not an issue
CallContext.SetData("__ClientIsClr", true);
responseStream = (MemoryStream)CoreChannel.SerializeBinaryMessage(responseMsg, _includeVersioning);
CallContext.FreeNamedDataSlot("__ClientIsClr");
responseStream.Position = 0;
responseHeaders = new TransportHeaders();
if (_protocol == Protocol.Http)
{
responseHeaders["Content-Type"] = CoreChannel.BinaryMimeType;
}
}
finally{
CallContext.FreeNamedDataSlot("__CustomErrorsEnabled");
}
return processing;
} // ProcessMessage