/*
RequestSubmitDone - Handle submit done callback.
This is our submit done handler, called by the underlying connection
code when a stream is available for our use. We save the stream for
later use and signal the wait event.
We also handle the continuation/termination of a BeginGetRequestStream,
by saving out the result and calling its callback if needed.
Input: SubmitStream - The stream we may write on.
Status - The status of the submission.
Returns: Nothing.
*/
internal void SetRequestSubmitDone(ConnectStream submitStream) {
GlobalLog.Enter("HttpWebRequest#" + ValidationHelper.HashString(this) + "::SetRequestSubmitDone", ValidationHelper.HashString(submitStream));
GlobalLog.ThreadContract(ThreadKinds.Unknown, "HttpWebRequest#" + ValidationHelper.HashString(this) + "::SetRequestSubmitDone");
if (!Async) {
ConnectionAsyncResult.InvokeCallback();
}
if (AllowWriteStreamBuffering) {
submitStream.EnableWriteBuffering();
}
if (submitStream.CanTimeout) {
submitStream.ReadTimeout = ReadWriteTimeout;
submitStream.WriteTimeout = ReadWriteTimeout;
}
if(Logging.On)Logging.Associate(Logging.Web, this, submitStream);
// The CBT won't actually be valid until we write to the stream for the first time, but we can create
// the TransportContext now. We don't query it until later, when we know it's available.
TransportContext transportContext = new ConnectStreamContext(submitStream);
ServerAuthenticationState.TransportContext = transportContext;
ProxyAuthenticationState.TransportContext = transportContext;
_SubmitWriteStream = submitStream;
// Async RTC requests only. Skip if ApplySetting has not been called so we can test
// without IOControl support/workarounds.
if (RtcState != null && RtcState.inputData != null && !RtcState.IsAborted)
{
RtcState.outputData = new byte[sizeof(RtcState.ControlChannelTriggerStatus)];
RtcState.result = _SubmitWriteStream.SetRtcOption(RtcState.inputData, RtcState.outputData);
if (!RtcState.IsEnabled())
{
// Abort request if we weren't able to enable RTC.
Abort(null, AbortState.Public);
}
RtcState.connectComplete.Set();
}
//
// This line is needed ONLY if we got a connect failure (Abort can still happen at random time)
// CallDone will check for the write side response processing and this is what we want.
// Note that [....] case already has a separate path to check for the response
//
if (Async && _CoreResponse != null && (object)_CoreResponse != (object)DBNull.Value)
{
GlobalLog.Assert(_CoreResponse is Exception, "SetRequestSubmitDone()|Found offensive response right after getting connection ({0}).", _CoreResponse);
submitStream.CallDone();
GlobalLog.Leave("HttpWebRequest#" + ValidationHelper.HashString(this) + "::SetRequestSubmitDone() - already have a core response", _CoreResponse.GetType().FullName);
return;
}
EndSubmitRequest();
GlobalLog.Leave("HttpWebRequest#" + ValidationHelper.HashString(this) + "::SetRequestSubmitDone");
}