Esempio n. 1
0
        /*++
            Uses an old Stream to resubmit buffered data using the current
             stream, this is used in cases of POST, or authentication,
             where we need to buffer upload data so that it can be resubmitted

            Input:

                OldStream - Old Stream that was previously used

            Returns:

                Nothing.

        --*/

        // 
        internal void ResubmitWrite(ConnectStream oldStream, bool suppressWrite) {
            GlobalLog.Enter("ConnectStream#" + ValidationHelper.HashString(this) + "::ResubmitWrite", ValidationHelper.HashString(oldStream));
            GlobalLog.ThreadContract(ThreadKinds.Sync, "ConnectStream#" + ValidationHelper.HashString(this) + "::ResubmitWrite");

            //
            // 




            //
            // we're going to resubmit
            //
            try {
                Interlocked.CompareExchange(ref m_CallNesting, Nesting.InternalIO, Nesting.Idle);
                GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::ResubmitWrite() Inc: " + m_CallNesting.ToString());

                GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::ResubmitWrite(), callNesting : " + m_CallNesting.ToString() + " IsClosed = " + IsClosed);
                //
                // no need to buffer here:
                // we're already resubmitting buffered data give it to the connection to put it on the wire again
                // we set BytesLeftToWrite to 0 'cause even on failure there can be no recovery,
                // so just leave it to IOError() to clean up and don't call ResubmitWrite()
                //
                ScatterGatherBuffers bufferedData = oldStream.BufferedData;
                SafeSetSocketTimeout(SocketShutdown.Send);
                if (!WriteChunked) {
                    if (!suppressWrite)
                        m_Connection.Write(bufferedData);
                }
                else {
                    // we have the data buffered, but we still want to chunk.

                    // first set this to disable Close() from sending a chunk terminator.
                    GlobalLog.Assert(m_HttpWriteMode != HttpWriteMode.None, "ConnectStream#{0}::ResubmitWrite()|m_HttpWriteMode == HttpWriteMode.None", ValidationHelper.HashString(this));
                    m_HttpWriteMode = HttpWriteMode.ContentLength;

                    if (bufferedData.Length==0) {
                        m_Connection.Write(NclConstants.ChunkTerminator, 0, NclConstants.ChunkTerminator.Length);
                    }
                    else {
                        int chunkHeaderOffset = 0;
                        byte[] chunkHeaderBuffer = GetChunkHeader(bufferedData.Length, out chunkHeaderOffset);
                        BufferOffsetSize[] dataBuffers = bufferedData.GetBuffers();
                        BufferOffsetSize[] buffers = new BufferOffsetSize[dataBuffers.Length + 3];
                        buffers[0] = new BufferOffsetSize(chunkHeaderBuffer, chunkHeaderOffset, chunkHeaderBuffer.Length - chunkHeaderOffset, false);
                        int index = 0;
                        foreach (BufferOffsetSize buffer in dataBuffers) {
                            buffers[++index] = buffer;
                        }
                        buffers[++index] = new BufferOffsetSize(NclConstants.CRLF, 0, NclConstants.CRLF.Length, false);
                        buffers[++index] = new BufferOffsetSize(NclConstants.ChunkTerminator, 0, NclConstants.ChunkTerminator.Length, false);

                        SplitWritesState splitState = new SplitWritesState(buffers);

                        BufferOffsetSize[] sendBuffers = splitState.GetNextBuffers();
                        while(sendBuffers != null){
                            m_Connection.MultipleWrite(sendBuffers);
                            sendBuffers = splitState.GetNextBuffers();
                        }
                    }
                }
                if(Logging.On && bufferedData.GetBuffers() != null) {
                    foreach (BufferOffsetSize bufferOffsetSize in bufferedData.GetBuffers()) {
                        if (bufferOffsetSize == null) {
                            Logging.Dump(Logging.Web, this, "ResubmitWrite", null, 0, 0);
                        }
                        else {
                            Logging.Dump(Logging.Web, this, "ResubmitWrite", bufferOffsetSize.Buffer, bufferOffsetSize.Offset, bufferOffsetSize.Size);
                        }
                    }
                }
                GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::ResubmitWrite() sent:" + bufferedData.Length.ToString() );
            }
            catch (Exception exception)
            {
                if (NclUtilities.IsFatal(exception)) throw;

                // A Fatal error
                WebException we = new WebException(NetRes.GetWebStatusString("net_connclosed", WebExceptionStatus.SendFailure),
                                               WebExceptionStatus.SendFailure,
                                               WebExceptionInternalStatus.RequestFatal,
                                               exception);
                IOError(we, false);
            }
            finally {
                Interlocked.CompareExchange(ref m_CallNesting, Nesting.Idle, Nesting.InternalIO);
                GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::ResubmitWrite(), callNesting : " + m_CallNesting.ToString() + " IsClosed = " + IsClosed);
            }
            m_BytesLeftToWrite = 0;
            CallDone();
            GlobalLog.Leave("ConnectStream#" + ValidationHelper.HashString(this) + "::ResubmitWrite", BytesLeftToWrite.ToString());
        }
 internal void SetNextRequest(System.Net.SplitWritesState splitWritesState, AsyncProtocolCallback callback)
 {
     this.SplitWritesState = splitWritesState;
     base.SetNextRequest(null, 0, 0, callback);
 }
 private void ProcessWrite(BufferOffsetSize[] buffers, SplitWriteAsyncProtocolRequest asyncRequest)
 {
     foreach (BufferOffsetSize size in buffers)
     {
         this.ValidateParameters(size.Buffer, size.Offset, size.Size);
     }
     if (Interlocked.Exchange(ref this._NestedWrite, 1) == 1)
     {
         throw new NotSupportedException(SR.GetString("net_io_invalidnestedcall", new object[] { (asyncRequest != null) ? "BeginWrite" : "Write", "write" }));
     }
     bool flag = false;
     try
     {
         SplitWritesState splitWritesState = new SplitWritesState(buffers);
         if (asyncRequest != null)
         {
             asyncRequest.SetNextRequest(splitWritesState, _ResumeAsyncWriteCallback);
         }
         this.StartWriting(splitWritesState, asyncRequest);
     }
     catch (Exception exception)
     {
         this._SslState.FinishWrite();
         flag = true;
         if (exception is IOException)
         {
             throw;
         }
         throw new IOException(SR.GetString("net_io_write"), exception);
     }
     finally
     {
         if ((asyncRequest == null) || flag)
         {
             this._NestedWrite = 0;
         }
     }
 }
 private void StartWriting(SplitWritesState splitWrite, SplitWriteAsyncProtocolRequest asyncRequest)
 {
     while (!splitWrite.IsDone)
     {
         if (this._SslState.CheckEnqueueWrite(asyncRequest))
         {
             return;
         }
         byte[] lastHandshakePayload = null;
         if (this._SslState.LastPayload != null)
         {
             lastHandshakePayload = this._SslState.LastPayload;
             this._SslState.LastPayloadConsumed();
         }
         BufferOffsetSize[] nextBuffers = splitWrite.GetNextBuffers();
         nextBuffers = this.EncryptBuffers(nextBuffers, lastHandshakePayload);
         if (asyncRequest != null)
         {
             IAsyncResult asyncResult = ((NetworkStream) this._SslState.InnerStream).BeginMultipleWrite(nextBuffers, _MulitpleWriteCallback, asyncRequest);
             if (!asyncResult.CompletedSynchronously)
             {
                 return;
             }
             ((NetworkStream) this._SslState.InnerStream).EndMultipleWrite(asyncResult);
         }
         else
         {
             ((NetworkStream) this._SslState.InnerStream).MultipleWrite(nextBuffers);
         }
         this._SslState.FinishWrite();
     }
     if (asyncRequest != null)
     {
         asyncRequest.CompleteUser();
     }
 }
Esempio n. 5
0
 internal void SetNextRequest(System.Net.SplitWritesState splitWritesState, AsyncProtocolCallback callback)
 {
     this.SplitWritesState = splitWritesState;
     base.SetNextRequest(null, 0, 0, callback);
 }