/// <include file='doc\HttpClientCertificate.uex' path='docs/doc[@for="HttpClientCertificate.Get"]/*' />
        /// <devdoc>
        ///    <para>Allows access to individual items in the collection by name.</para>
        /// </devdoc>
        public override String Get(String field)
        {
            if (field == null)
            {
                return(String.Empty);
            }

            field = field.ToLower(CultureInfo.InvariantCulture);

            switch (field)
            {
            case "cookie":
                return(Cookie);

            case "flags":
                return(Flags.ToString("G"));

            case "keysize":
                return(KeySize.ToString("G"));

            case "secretkeysize":
                return(SecretKeySize.ToString());

            case "issuer":
                return(Issuer);

            case "serverissuer":
                return(ServerIssuer);

            case "subject":
                return(Subject);

            case "serversubject":
                return(ServerSubject);

            case "serialnumber":
                return(SerialNumber);

            case "certificate":
                return(System.Text.Encoding.Default.GetString(Certificate));

            case "binaryissuer":
                return(System.Text.Encoding.Default.GetString(BinaryIssuer));

            case "publickey":
                return(System.Text.Encoding.Default.GetString(PublicKey));

            case "encoding":
                return(CertEncoding.ToString("G"));

            case "validfrom":
                return(HttpUtility.FormatHttpDateTime(ValidFrom));

            case "validuntil":
                return(HttpUtility.FormatHttpDateTime(ValidUntil));
            }

            if (field.StartsWith("issuer"))
            {
                return(ExtractString(Issuer, field.Substring(6)));
            }

            if (field.StartsWith("subject"))
            {
                if (field.Equals("subjectemail"))
                {
                    return(ExtractString(Subject, "e"));
                }
                else
                {
                    return(ExtractString(Subject, field.Substring(7)));
                }
            }

            if (field.StartsWith("serversubject"))
            {
                return(ExtractString(ServerSubject, field.Substring(13)));
            }

            if (field.StartsWith("serverissuer"))
            {
                return(ExtractString(ServerIssuer, field.Substring(12)));
            }

            return(String.Empty);
        }
        internal static unsafe bool ProcessRangeRequest(HttpContext context, string physicalPath, long fileLength, string rangeHeader, string etag, DateTime lastModified)
        {
            long         offset;
            long         length;
            HttpRequest  request  = context.Request;
            HttpResponse response = context.Response;
            bool         flag     = false;

            if (fileLength <= 0L)
            {
                SendRangeNotSatisfiable(response, fileLength);
                return(true);
            }
            string ifRangeHeader = request.Headers["If-Range"];

            if ((ifRangeHeader != null) && (ifRangeHeader.Length > 1))
            {
                if (ifRangeHeader[0] == '"')
                {
                    if (ifRangeHeader != etag)
                    {
                        return(flag);
                    }
                }
                else
                {
                    if ((ifRangeHeader[0] == 'W') && (ifRangeHeader[1] == '/'))
                    {
                        return(flag);
                    }
                    if (IsOutDated(ifRangeHeader, lastModified))
                    {
                        return(flag);
                    }
                }
            }
            int index = rangeHeader.IndexOf('=');

            if ((index == -1) || (index == (rangeHeader.Length - 1)))
            {
                return(flag);
            }
            int  startIndex = index + 1;
            bool flag2      = true;
            bool flag4      = false;

            ByteRange[] rangeArray = null;
            int         num5       = 0;
            long        num6       = 0L;

            while ((startIndex < rangeHeader.Length) && flag2)
            {
                bool flag3;
                flag2 = GetNextRange(rangeHeader, ref startIndex, fileLength, out offset, out length, out flag3);
                if (!flag2)
                {
                    break;
                }
                if (flag3)
                {
                    if (rangeArray == null)
                    {
                        rangeArray = new ByteRange[0x10];
                    }
                    if (num5 >= rangeArray.Length)
                    {
                        ByteRange[] rangeArray2 = new ByteRange[rangeArray.Length * 2];
                        int         len         = rangeArray.Length * Marshal.SizeOf(rangeArray[0]);
                        fixed(ByteRange *rangeRef = rangeArray)
                        {
                            fixed(ByteRange *rangeRef2 = rangeArray2)
                            {
                                StringUtil.memcpyimpl((byte *)rangeRef, (byte *)rangeRef2, len);
                            }
                        }

                        rangeArray = rangeArray2;
                    }
                    rangeArray[num5].Offset = offset;
                    rangeArray[num5].Length = length;
                    num5++;
                    num6 += length;
                    if (num6 > (fileLength * 5L))
                    {
                        flag4 = true;
                        break;
                    }
                }
            }
            if (!flag2)
            {
                return(flag);
            }
            if (flag4)
            {
                SendBadRequest(response);
                return(true);
            }
            if (num5 == 0)
            {
                SendRangeNotSatisfiable(response, fileLength);
                return(true);
            }
            string mimeMapping = MimeMapping.GetMimeMapping(physicalPath);

            if (num5 == 1)
            {
                offset = rangeArray[0].Offset;
                length = rangeArray[0].Length;
                response.ContentType = mimeMapping;
                string str3 = string.Format(CultureInfo.InvariantCulture, "bytes {0}-{1}/{2}", new object[] { offset, (offset + length) - 1L, fileLength });
                response.AppendHeader("Content-Range", str3);
                SendFile(physicalPath, offset, length, fileLength, context);
            }
            else
            {
                response.ContentType = "multipart/byteranges; boundary=<q1w2e3r4t5y6u7i8o9p0zaxscdvfbgnhmjklkl>";
                string s = "Content-Type: " + mimeMapping + "\r\n";
                for (int i = 0; i < num5; i++)
                {
                    offset = rangeArray[i].Offset;
                    length = rangeArray[i].Length;
                    response.Write("--<q1w2e3r4t5y6u7i8o9p0zaxscdvfbgnhmjklkl>\r\n");
                    response.Write(s);
                    response.Write("Content-Range: ");
                    string str4 = string.Format(CultureInfo.InvariantCulture, "bytes {0}-{1}/{2}", new object[] { offset, (offset + length) - 1L, fileLength });
                    response.Write(str4);
                    response.Write("\r\n\r\n");
                    SendFile(physicalPath, offset, length, fileLength, context);
                    response.Write("\r\n");
                }
                response.Write("--<q1w2e3r4t5y6u7i8o9p0zaxscdvfbgnhmjklkl>--\r\n\r\n");
            }
            response.StatusCode = 0xce;
            response.AppendHeader("Last-Modified", HttpUtility.FormatHttpDateTime(lastModified));
            response.AppendHeader("Accept-Ranges", "bytes");
            response.AppendHeader("ETag", etag);
            response.AppendHeader("Cache-Control", "public");
            return(true);
        }
Example #3
0
        internal static bool ProcessRangeRequest(HttpContext context,
                                                 string physicalPath,
                                                 long fileLength,
                                                 string rangeHeader,
                                                 string etag,
                                                 DateTime lastModified)
        {
            HttpRequest  request  = context.Request;
            HttpResponse response = context.Response;
            bool         handled  = false;

            // return "416 Requested range not satisfiable" if the file length is zero.
            if (fileLength <= 0)
            {
                SendRangeNotSatisfiable(response, fileLength);
                handled = true;
                return(handled);
            }

            string ifRangeHeader = request.Headers["If-Range"];

            if (ifRangeHeader != null && ifRangeHeader.Length > 1)
            {
                // Is this an ETag or a Date? We only need to check two
                // characters; an ETag either begins with W/ or it is quoted.
                if (ifRangeHeader[0] == '"')
                {
                    // it's a strong ETag
                    if (ifRangeHeader != etag)
                    {
                        // the etags do not match, and we will therefore return the entire response
                        return(handled);
                    }
                }
                else if (ifRangeHeader[0] == 'W' && ifRangeHeader[1] == '/')
                {
                    // it's a weak ETag, and is therefore not usable for sub-range retrieval and
                    // we will return the entire response
                    return(handled);
                }
                else
                {
                    // It's a date. If it is greater than or equal to the last-write time of the file, we can send the range.
                    if (IsOutDated(ifRangeHeader, lastModified))
                    {
                        return(handled);
                    }
                }
            }

            // the expected format is "bytes = <range1>[, <range2>, ...]"
            // where <range> is "<first_byte_pos>-[<last_byte_pos>]" or "-<last_n_bytes>".
            int indexOfEquals = rangeHeader.IndexOf('=');

            if (indexOfEquals == -1 || indexOfEquals == rangeHeader.Length - 1)
            {
                //invalid syntax
                return(handled);
            }

            // iterate through the byte ranges and write each satisfiable range to the response
            int  startIndex = indexOfEquals + 1;
            bool isRangeHeaderSyntacticallyValid = true;
            long offset;
            long length;
            bool isSatisfiable;
            bool exceededMax = false;

            ByteRange[] byteRanges      = null;
            int         byteRangesCount = 0;
            long        totalBytes      = 0;

            while (startIndex < rangeHeader.Length && isRangeHeaderSyntacticallyValid)
            {
                isRangeHeaderSyntacticallyValid = GetNextRange(rangeHeader, ref startIndex, fileLength, out offset, out length, out isSatisfiable);
                if (!isRangeHeaderSyntacticallyValid)
                {
                    break;
                }
                if (!isSatisfiable)
                {
                    continue;
                }
                if (byteRanges == null)
                {
                    byteRanges = new ByteRange[16];
                }
                if (byteRangesCount >= byteRanges.Length)
                {
                    // grow byteRanges array
                    ByteRange[] buffer    = new ByteRange[byteRanges.Length * 2];
                    int         byteCount = byteRanges.Length * Marshal.SizeOf(byteRanges[0]);
                    unsafe
                    {
                        fixed(ByteRange *src = byteRanges, dst = buffer)
                        {
                            StringUtil.memcpyimpl((byte *)src, (byte *)dst, byteCount);
                        }
                    }
                    byteRanges = buffer;
                }
                byteRanges[byteRangesCount].Offset = offset;
                byteRanges[byteRangesCount].Length = length;
                byteRangesCount++;
                // IIS imposes this limitation too, and sends "400 Bad Request" if exceeded
                totalBytes += length;
                if (totalBytes > fileLength * MAX_RANGE_ALLOWED)
                {
                    exceededMax = true;
                    break;
                }
            }

            if (!isRangeHeaderSyntacticallyValid)
            {
                return(handled);
            }

            if (exceededMax)
            {
                SendBadRequest(response);
                handled = true;
                return(handled);
            }

            if (byteRangesCount == 0)
            {
                // we parsed the Range header and found no satisfiable byte ranges, so return "416 Requested Range Not Satisfiable"
                SendRangeNotSatisfiable(response, fileLength);
                handled = true;
                return(handled);
            }

            string contentType = MimeMapping.GetMimeMapping(physicalPath);

            if (byteRangesCount == 1)
            {
                offset = byteRanges[0].Offset;
                length = byteRanges[0].Length;
                response.ContentType = contentType;
                string contentRange = String.Format(CultureInfo.InvariantCulture, CONTENT_RANGE_FORMAT, offset, offset + length - 1, fileLength);
                response.AppendHeader("Content-Range", contentRange);

                SendFile(physicalPath, offset, length, fileLength, context);
            }
            else
            {
                response.ContentType = MULTIPART_CONTENT_TYPE;
                string contentRange;
                string partialContentType = "Content-Type: " + contentType + "\r\n";
                for (int i = 0; i < byteRangesCount; i++)
                {
                    offset = byteRanges[i].Offset;
                    length = byteRanges[i].Length;
                    response.Write(MULTIPART_RANGE_DELIMITER);
                    response.Write(partialContentType);
                    response.Write("Content-Range: ");
                    contentRange = String.Format(CultureInfo.InvariantCulture, CONTENT_RANGE_FORMAT, offset, offset + length - 1, fileLength);
                    response.Write(contentRange);
                    response.Write("\r\n\r\n");
                    SendFile(physicalPath, offset, length, fileLength, context);
                    response.Write("\r\n");
                }
                response.Write(MULTIPART_RANGE_END);
            }

            // if we make it here, we're sending a "206 Partial Content" status
            response.StatusCode = 206;
            response.AppendHeader("Last-Modified", HttpUtility.FormatHttpDateTime(lastModified));
            response.AppendHeader("Accept-Ranges", "bytes");
            response.AppendHeader("ETag", etag);
            response.AppendHeader("Cache-Control", "public");

            handled = true;
            return(handled);
        }
Example #4
0
        public override string Get(string field)
        {
            if (field != null)
            {
                field = field.ToLower(CultureInfo.InvariantCulture);
                switch (field)
                {
                case "cookie":
                    return(this.Cookie);

                case "flags":
                    return(this.Flags.ToString("G", CultureInfo.InvariantCulture));

                case "keysize":
                    return(this.KeySize.ToString("G", CultureInfo.InvariantCulture));

                case "secretkeysize":
                    return(this.SecretKeySize.ToString(CultureInfo.InvariantCulture));

                case "issuer":
                    return(this.Issuer);

                case "serverissuer":
                    return(this.ServerIssuer);

                case "subject":
                    return(this.Subject);

                case "serversubject":
                    return(this.ServerSubject);

                case "serialnumber":
                    return(this.SerialNumber);

                case "certificate":
                    return(Encoding.Default.GetString(this.Certificate));

                case "binaryissuer":
                    return(Encoding.Default.GetString(this.BinaryIssuer));

                case "publickey":
                    return(Encoding.Default.GetString(this.PublicKey));

                case "encoding":
                    return(this.CertEncoding.ToString("G", CultureInfo.InvariantCulture));

                case "validfrom":
                    return(HttpUtility.FormatHttpDateTime(this.ValidFrom));

                case "validuntil":
                    return(HttpUtility.FormatHttpDateTime(this.ValidUntil));
                }
                if (StringUtil.StringStartsWith(field, "issuer"))
                {
                    return(this.ExtractString(this.Issuer, field.Substring(6)));
                }
                if (StringUtil.StringStartsWith(field, "subject"))
                {
                    if (field.Equals("subjectemail"))
                    {
                        return(this.ExtractString(this.Subject, "e"));
                    }
                    return(this.ExtractString(this.Subject, field.Substring(7)));
                }
                if (StringUtil.StringStartsWith(field, "serversubject"))
                {
                    return(this.ExtractString(this.ServerSubject, field.Substring(13)));
                }
                if (StringUtil.StringStartsWith(field, "serverissuer"))
                {
                    return(this.ExtractString(this.ServerIssuer, field.Substring(12)));
                }
            }
            return(string.Empty);
        }