internal void WriteHeaders(bool async) {
GlobalLog.Enter("ConnectStream#" + ValidationHelper.HashString(this) + "::WriteHeaders", "Connection#" + ValidationHelper.HashString(m_Connection) + ", headers buffer size = " + m_Request.WriteBuffer.Length.ToString());
WebExceptionStatus error = WebExceptionStatus.SendFailure;
if (!ErrorInStream)
{
//m_Request.WriteBuffer may be set to null on resubmit before method exits
byte[] writeBuffer = m_Request.WriteBuffer;
try
{
Interlocked.CompareExchange(ref m_CallNesting, Nesting.InternalIO, Nesting.Idle);
GlobalLog.Print("WriteHeaders() callNesting: " + m_CallNesting.ToString());
if(async)
{
WriteHeadersCallbackState state = new WriteHeadersCallbackState(m_Request, this);
IAsyncResult ar = m_Connection.UnsafeBeginWrite(writeBuffer,0,writeBuffer.Length, m_WriteHeadersCallback, state);
if (ar.CompletedSynchronously) {
m_Connection.EndWrite(ar);
m_Connection.CheckStartReceive(m_Request);
error = WebExceptionStatus.Success;
}
else {
error = WebExceptionStatus.Pending;
#if DEBUG
_PendingResult = ar;
#endif
}
}
else
{
SafeSetSocketTimeout(SocketShutdown.Send);
m_Connection.Write(writeBuffer, 0, writeBuffer.Length);
m_Connection.CheckStartReceive(m_Request);
error = WebExceptionStatus.Success;
}
if (Logging.On) Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_sending_headers, m_Request.Headers.ToString(true)));
}
catch (Exception e) {
if (NclUtilities.IsFatal(e)) throw;
GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::WriteHeaders Exception: "+e.ToString());
if (e is IOException || e is ObjectDisposedException)
{
//new connection but reset from server on inital send
if(!m_Connection.AtLeastOneResponseReceived && !m_Request.BodyStarted){
e = new WebException(
NetRes.GetWebStatusString("net_connclosed", error),
error,
WebExceptionInternalStatus.Recoverable,
e);
}
else{
e = new WebException(
NetRes.GetWebStatusString("net_connclosed", error),
error,
m_Connection.AtLeastOneResponseReceived ? WebExceptionInternalStatus.Isolated : WebExceptionInternalStatus.RequestFatal,
e);
}
}
IOError(e, false);
}
finally {
if(error != WebExceptionStatus.Pending) {
Interlocked.CompareExchange(ref m_CallNesting, Nesting.Idle, Nesting.InternalIO);
GlobalLog.Print("WriteHeaders() callNesting: " + m_CallNesting.ToString());
}
}
}
else
{
GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::WriteHeaders() ignoring since ErrorInStream = true");
}
if(error != WebExceptionStatus.Pending) {
//if error is Pending, and this is async, the request callback will be invoked from the stream callback.
m_Request.WriteHeadersCallback(error, this, async);
}
GlobalLog.Leave("ConnectStream#" + ValidationHelper.HashString(this) + "::WriteHeaders", error.ToString());
}