/// <summary> /// Sends the body of a chunked transfer-encoded message /// </summary> /// <param name="socket"></param> /// <param name="abortEvent"></param> /// <param name="message"></param> internal protected void SendBodyChunked(Socket socket, ManualResetEvent abortEvent, HttpMessage message, EventHandler <HttpMessageProgressEventArgs> onProgress, object stateObject) { int segmentNumber = 0; int totalBytesSent = 0; byte[] body = message.ToByteArray(false /* no headers */, true /* just the body */); while (true) { // if we have sent the entire message then we can abortEvent if (totalBytesSent > body.Length) { break; } // start out with a full segment size (this is just the buffer size by which we will send - 8k seems to be really common although i have no idea why other than that it's a power of 2...) int chunkSize = MAX_SEGMENT_SIZE_CHUNKED; // adjust how much we need to send to complete the message if (chunkSize > (body.Length - totalBytesSent)) { chunkSize = (body.Length - totalBytesSent); } // bump up the segment number segmentNumber++; // create a chunk of data to send byte[] bytes = new byte[chunkSize]; Buffer.BlockCopy(body, totalBytesSent, bytes, 0, chunkSize); // create a chunk around the data HttpChunk chunk = new HttpChunk(bytes); // send the data int bytesSent = HttpUtils.SendBytes(socket, chunk.ToByteArray()); // if any data was sent if (bytesSent > 0) { // figure out how much as data, minus the chunks control chars int actualBytesSent = bytesSent - chunk.GetNonDataByteCount(); // if the chunksize is zero or less then we'll return what was sent if (chunkSize > 0) { // all other times it'll not count the non data byte count in the chunk bytesSent = actualBytesSent; } } // tally the number of bytes we have sent totalBytesSent += bytesSent; // notify the callback of our progress this.OnProgress(onProgress, this, new HttpMessageProgressEventArgs(message, false, bytes, totalBytesSent, stateObject)); // clear that buffer immediately bytes = null; // see if we have been instructed to abortEvent reading if (abortEvent != null) { if (abortEvent.WaitOne(1, false)) { throw new HttpMessageWriterAbortedException(message); } } } }