Пример #1
0
        public async Task ReadAndExecuteRequestAsync()
        {
            if (MultipartPartParser.IsEndPart)
            {
                HandleMultipartReadError("End part detected after reading Headers. No more parts detected.");
            }
            if (!MultipartPartParser.IsEndPart && !string.IsNullOrWhiteSpace(MultipartPartParser.Filename))
            {
                await ExecuteFunctionAsync(MultipartPartParser);

                // move the stream foward until we get to the next part
                MultipartPartParser = MultipartPartParser.ReadUntilNextPart();
                if (MultipartPartParser != null)
                {
                    HandleMultipartReadError("Only one part is supported for multi-part.");
                }
                return;
            }
            HandleMultipartReadError("Error reading multi-part");
        }
Пример #2
0
        /// <summary>
        /// Reads the stream, if this part has completed the nextpart is returned
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="offset"></param>
        /// <param name="count"></param>
        /// <param name="nextpart"></param>
        /// <returns></returns>
        public int ReadForNextPart(byte[] buffer, int offset, int count, out MultipartPartParser nextpart)
        {
            // If we have found our next part we have already finsihed this part and should stop here
            if (NextPart != null || IsEndPart)
            {
                nextpart = NextPart;
                return(0);
            }

            // the search buffer is the place where we will scan for part bounderies. We need it to be just
            // a bit bigger than than the size requested, to ensure we dont accidnetly send part of a boundary
            // without realising it
            byte[] searchBuffer = new byte[count + BoundaryWithNewLinePrepend.Length];

            int bytesReadThisCall = 0;

            // first read from our local buffer
            int bytesToReadFromLocalBuffer = Math.Min((int)LocalBuffer.Length, searchBuffer.Length);

            if (bytesToReadFromLocalBuffer > 0)
            {
                bytesReadThisCall += LocalBuffer.Read(searchBuffer, bytesReadThisCall, bytesToReadFromLocalBuffer);
            }

            // if we could not fill our search buffer with our local buffer then read from the multipart stream
            int bytesToReadFromStream = searchBuffer.Length - bytesReadThisCall;

            bytesToReadFromStream = Math.Min(bytesToReadFromStream, (int)MultipartStream.Length - (int)MultipartStream.Position);

            if (bytesToReadFromStream > 0)
            {
                bytesReadThisCall += MultipartStream.Read(searchBuffer, bytesReadThisCall, bytesToReadFromStream);
            }

            // the number of bytes returned will be one of three cases
            // 1. There is still plenty to return so we will return the 'count' they asked for
            // 2. We have emptied the stream, we will return the bytes read
            // 3. We have run into a new boundary, we will return the bytes up to the boundary end
            int  bytesReturned;
            bool isEndOfPart = SearchBytePattern(BoundaryWithNewLinePrepend, searchBuffer, out bytesReturned);

            // we can only return the parts we know for sure are not part of the next boundary
            // which is the bytes we read minus the boundary length. This will also ensure we
            // get back to the count we were originally asked for. We also need to make sure we
            // return 0 bytes if we can not gaurentee there are no boundaries parts in what we
            // did manage to read
            if (!isEndOfPart)
            {
                bytesReturned = Math.Max(0, bytesReadThisCall - BoundaryWithNewLinePrepend.Length);
            }



            Buffer.BlockCopy(searchBuffer, 0, buffer, offset, bytesReturned);

            // We need to handle the bytes that did not get returned by putting them back into
            // the local buffer
            int bytesNotReturned = bytesReadThisCall - bytesReturned;

            ReinsertIntoLocalBuffer(searchBuffer, bytesReturned, bytesNotReturned);

            nextpart = null;
            if (isEndOfPart)
            {
                // the boundary we were looking for had a newline appended to it
                // we dont want to send the newline to the next part so we will skip
                LocalBuffer.Position += NewLine.Length;
                NextPart              = new MultipartPartParser(MultipartStream, Encoding, _log, LocalBuffer);

                // The next part may actually just the be end indicator, if thats the case
                // we will null it and not return it
                if (NextPart.IsEndPart)
                {
                    NextPart = null;
                }
                nextpart = NextPart;
            }


            return(bytesReturned);
        }
Пример #3
0
 protected MultipartReader(Stream stream, IServiceLogRepository log)
 {
     MultipartPartParser = new MultipartPartParser(stream, log);
     _log = log;
 }