Exemplo n.º 1
0
        private void RespondWithFile(File422 file, WebRequest req)
        {
            Stream fs = file.OpenReadOnly();

            if (req.Headers.ContainsKey("range"))
            {
                WriteWithRangeHeader(file, fs, req);
                return;
            }

            // Send response code and headers
            string response = "HTTP/1.1 200 OK\r\n" +
                              "Content-Length: " + fs.Length + "\r\n" +
                              "Content-Type: " + file.GetContentType() + "\r\n\r\n";

            byte[] responseBytes = Encoding.ASCII.GetBytes(response);
            req.WriteResponse(responseBytes, 0, responseBytes.Length);

            while (true)
            {
                byte[] buf  = new byte[4096];
                int    read = fs.Read(buf, 0, buf.Length);
                if (read == 0)
                {
                    break;
                }
                req.WriteResponse(buf, 0, read);
            }
            fs.Close();
        }
Exemplo n.º 2
0
        /// <summary>
        /// Writes the with range header.
        /// </summary>
        private void WriteWithRangeHeader(File422 file, Stream fs, WebRequest req)
        {
            String[] ranges = req.Headers["range"].Trim().Substring("byte= ".Length).Split('-');

            long from;

            Int64.TryParse(ranges[0], out from);
            if (fs.Length <= from)
            {
                string invalid = "HTTP/1.1 416 Requested Range Not Satisfiable\r\n\r\n";
                byte[] invalidResponseBytes = Encoding.ASCII.GetBytes(invalid);
                req.WriteResponse(invalidResponseBytes, 0, invalidResponseBytes.Length);
            }

            long to;

            if (ranges[1] != string.Empty)
            {
                Int64.TryParse(ranges[1], out to);
            }
            else
            {
                to = fs.Length - 1;
            }

            // Send response code and headers
            string response = "HTTP/1.1 206 Partial content\r\n" +
                              "Content-Range: bytes " + from.ToString() + "-" + to.ToString() + "/" + fs.Length.ToString() + "\r\n" +
                              "Content-Length: " + (to + 1 - from).ToString() + "\r\n" +
                              "Content-Type: " + file.GetContentType() + "\r\n\r\n";

            byte[] responseBytes = Encoding.ASCII.GetBytes(response);
            req.WriteResponse(responseBytes, 0, responseBytes.Length);


            fs.Seek(from, SeekOrigin.Begin);
            while (true)
            {
                byte[] buf  = new byte[4096];
                int    read = 0;
                read = fs.Read(buf, 0, buf.Length);
                if (read == 0)
                {
                    break;
                }
                req.WriteResponse(buf, 0, read);
                if (fs.Position >= to)
                {
                    break;
                }
            }
            fs.Close();
        }
Exemplo n.º 3
0
        private void PUTHandler(WebRequest req, string name, Dir422 dir)
        {
            if (dir.ContainsFile(name, false) || name.Contains("\\") || name.Contains("/"))
            {
                string bodyMessage = "Invalid: File already exists or filename is invalid";
                string template    = "HTTP/1.1 400 Bad Request\r\n" +
                                     "Content-Type: text/html\r\n" +
                                     "Content-Length: {0}\r\n\r\n" +
                                     "{1}";

                string response      = string.Format(template, Encoding.ASCII.GetBytes(bodyMessage).Length, bodyMessage);
                byte[] responseBytes = Encoding.ASCII.GetBytes(response);
                req.WriteResponse(responseBytes, 0, responseBytes.Length);
                return;
            }

            File422    file = dir.CreateFile(name);
            FileStream fs   = (FileStream)file.OpenReadWrite();

            long fileSize = 0;

            Int64.TryParse(req.BodySize, out fileSize);
            int totalread = 0;

            while (true)
            {
                byte[] buf  = new byte[4096];
                int    read = req.Body.Read(buf, 0, buf.Length);
                fs.Write(buf, 0, read);
                totalread += read;
                if ((read == 0) || read < buf.Length && totalread >= fileSize)
                {
                    break;
                }
            }
            fs.Dispose(); fs.Close();
            req.WriteHTMLResponse("Successfully uploaded file: " + name);
        }
Exemplo n.º 4
0
        private void SendFileContent(File422 file, WebRequest req)
        {
            byte[]        buffer = new byte[1024]; //1kb buffer
            StringBuilder sb     = new StringBuilder();
            string        contentType;             //default contentType
            string        status = "200 Success";  //default status
            int           initialPos;
            long          contentLength, startByte = 0;

            //find extension
            if (!exts.TryGetValue(Path.GetExtension(file.Name).ToLower(),
                                  out contentType))
            {
                //default
                contentType = "application/octet-stream";
            }

            using (Stream fs = file.OpenReadOnly()){
                contentLength = fs.Length;
                //if client sent a range request.
                if (req.Headers.ContainsKey("range"))
                {
                    var t = req.GetRangeHeader(fs.Length);
                    //find range
                    if (t == null)
                    {
                        string pageHTML = "<html><h1>416 REQUESTED RANGE NOT SATISFIABLE</h1></html>";
                        req.WriteRangeNotSatisfiableResponse(pageHTML,
                                                             fs.Length.ToString());
                        return;
                    }
                    status        = "206 Partial Content";
                    startByte     = t.Item1;                 //start offset byte
                    contentLength = (t.Item2 - t.Item1) + 1; //because contentLength is the length, not last byte.
                }

                sb.Append("HTTP/1.1 " + status + "\r\n");
                sb.Append("Content-Length: " + contentLength + "\r\n");
                sb.Append("Content-Type: " + contentType + "\r\n");

                //we need this so that the file downloads, instead
                //of trying to switch views.

                /*sb.Append("Content-Disposition: attachment; filename=\"" +
                 *  file.Name + "\"\r\n");*/

                sb.Append("\r\n");
                initialPos = sb.Length;

                ASCIIEncoding.ASCII.GetBytes(sb.ToString()).CopyTo(buffer, 0);

                if (req.Headers.ContainsKey("range"))
                {
                    int totalBytesRead;
                    int bytesRead = 0;

                    //seek to startbyte.
                    fs.Seek(startByte, SeekOrigin.Begin);

                    //our initial read has to be the smaller of one of these 2.
                    int initialRead = ((buffer.Length - initialPos) < contentLength)
                        ? buffer.Length - initialPos
                        : (int)contentLength; // if (buffer.Length - initialPos) >= cL

                    totalBytesRead = fs.Read(buffer, initialPos, initialRead);

                    //Console.WriteLine(ASCIIEncoding.ASCII.GetString(buffer));

                    //has to be what we had initially plus what we just read.
                    req.WriteResponse(buffer, initialPos + initialRead);
                    Array.Clear(buffer, 0, buffer.Length);

                    //if we still have not read up to content length, keep reading.
                    if (totalBytesRead < contentLength)
                    {
                        int subsequentRead = (buffer.Length < contentLength)
                            ? buffer.Length
                            : (int)contentLength; // if (buffer.Length - initialPos) >= cL

                        //keep track of previous total bytes
                        int prevTotalBytesRead = totalBytesRead;

                        while ((bytesRead = fs.Read(buffer, 0, subsequentRead)) != 0 &&
                               (totalBytesRead += bytesRead) < contentLength)
                        {
                            prevTotalBytesRead = totalBytesRead;

                            req.WriteResponse(buffer, bytesRead);
                            Array.Clear(buffer, 0, buffer.Length);
                        }

                        if (totalBytesRead >= contentLength)
                        {
                            //we subtract the value of totalBytes right before it was more than contentLength,
                            //from content length (contentLength - prevTotalBytesRead)
                            //this gives us the last bit we need to write to achieve the range requested's length.
                            req.WriteResponse(buffer, (int)contentLength - prevTotalBytesRead);
                        }
                    }
                }
                else
                {
                    fs.Read(buffer, initialPos, buffer.Length - initialPos);
                    req.WriteResponse(buffer);

                    while (fs.Read(buffer, 0, buffer.Length) != 0)
                    {
                        req.WriteResponse(buffer);
                        Array.Clear(buffer, 0, buffer.Length);
                    }
                }

                req.CloseResponse();
            }
        }
Exemplo n.º 5
0
        void SendFileRange(File422 file, long start, long end, long chunkSize, WebRequest req)
        {
            if (end < start)
            {
                throw new ArgumentException("Invalid start and end range");
            }

            var fileStream = file.OpenReadOnly();

            long fileSize = fileStream.Length;

            if (start > end)
            {
                req.WriteNotFoundResponse("Invalid Range Header Specified");
            }

            if (end == 0)
            {
                end = fileSize;
            }
            req.Headers = new System.Collections.Concurrent.ConcurrentDictionary <string, string> ();

            if (end - start + 1 < chunkSize)
            {
                // only need to send 1 response
                string contentType = GetContentType(file.Name);
                if (contentType != null)
                {
                    req.Headers ["Content-Type"] = contentType;
                }
                else
                {
                    req.Headers ["Content-Type"] = "text/plain";
                }
                var fileContents = GetFileRange(fileStream, start, end);
                req.WriteResponse("206 Partial Content", fileContents);
            }
            else
            {
                // need to send multiple responses
                string boundary = "5187ab27335732";

                string contentType = GetContentType(file.Name);
                if (contentType != null)
                {
                    req.Headers ["Content-Type"] = contentType;
                }


                long offset = start;
                long sent   = 0;
                req.Headers ["Accept-Ranges"] = "bytes";

                long sizeToSend = end - start + 1;

                while (sent <= sizeToSend)
                {
                    long currentSize = (sizeToSend - sent) < chunkSize ? sizeToSend - sent: chunkSize;

                    if (offset + currentSize > fileSize)
                    {
                        currentSize = fileSize - offset + 1;
                    }


                    if (currentSize <= 0)
                    {
                        break;
                    }
                    //Console.WriteLine ("Getting file range [{0}, {1}]", offset, offset + currentSize);
                    var fileContents = GetFileRange(fileStream, offset, offset + currentSize);

                    req.Headers ["Content-Range"] = String.Format("bytes {0}-{1}/{2}", offset, currentSize + offset, sizeToSend);


                    req.WriteResponse("206 PartialContent", fileContents);

                    offset += currentSize + 1;
                    sent   += currentSize;
                }
            }
        }