Пример #1
0
        /// <summary>
        /// 生成表单和文件
        /// </summary>
        /// <param name="request">请求</param>
        /// <param name="streamReader">数据读取器</param>
        /// <param name="boundary">边界</param>
        private static void GenerateMultipartFormAndFiles(HttpRequest request, IByteStream stream, IContext context, string boundary)
        {
            byte[]                  boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary);
            int                     maxPosition   = stream.Length - Encoding.ASCII.GetBytes("--\r\n").Length;
            IByteStream             reader        = stream;
            List <HttpFile>         files         = new List <HttpFile>();
            HttpNameValueCollection form          = new HttpNameValueCollection();

            reader.ReadSkip(boundaryBytes.Length);
            while (reader.ReaderIndex < maxPosition)
            {
                int headLength = reader.BytesBefore(DoubleCRLF) + DoubleCRLF.Length;
                if (headLength < DoubleCRLF.Length)
                {
                    break;
                }

                string head       = reader.ReadString(Encoding.UTF8, headLength);
                int    bodyLength = reader.BytesBefore(boundaryBytes);
                if (bodyLength < 0)
                {
                    break;
                }
                string        fileName;
                MultipartHead mHead = new MultipartHead(head);
                if (mHead.TryGetFileName(out fileName) == true)
                {
                    byte[]   bytes = reader.ReadBytes(bodyLength);
                    HttpFile file  = new HttpFile(mHead.Name, fileName, bytes);
                    files.Add(file);
                }
                else
                {
                    byte[] byes  = reader.ReadBytes(bodyLength);
                    string value = byes.Length == 0 ? null : Utility.UrlDecode(byes, Encoding.UTF8);
                    form.Add(mHead.Name, value);
                }
                reader.ReadSkip(boundaryBytes.Length);
            }

            request.Form  = form;
            request.Files = files.ToArray();
        }
Пример #2
0
        /// <summary>
        /// 尝试当作http头解析,生成请求对象
        /// 如果不是http头则返回false
        /// </summary>
        /// <param name="context">上下文</param>
        /// <param name="request">请求对象</param>
        /// <param name="headerLength">请求头长度</param>
        /// <param name="contentLength">请求内容长度</param>
        /// <returns></returns>
        private static bool TryGetRequest(IContext context, IByteStream stream, bool isSSL, out HttpRequest request, out int headerLength, out int contentLength)
        {
            request       = null;
            headerLength  = 0;
            contentLength = 0;
            IByteStream reader  = stream;
            ChannelBase channel = context.Channel;

            if (channel == null)
            {
                return(false);
            }
            // HTTP Method
            reader.SetReaderIndex(0);
            int methodLength = reader.BytesBefore(Space);

            if (methodLength < 0 || methodLength > MedthodMaxLength)
            {
                return(false);
            }
            string methodName = reader.ReadString(Encoding.ASCII, methodLength);

            if (MethodNames.Contains(methodName) == false)
            {
                return(false);
            }
            HttpMethod httpMethod = (HttpMethod)Enum.Parse(typeof(HttpMethod), methodName, true);

            // HTTP Path
            reader.ReadSkip(1);
            int pathLength = reader.BytesBefore(Space);

            if (pathLength < 0)
            {
                return(false);
            }
            string path = reader.ReadString(Encoding.ASCII, pathLength);


            // HTTP Version
            reader.ReadSkip(1);
            if (reader.StartWith(HttpVersion11) == false)
            {
                return(false);
            }
            reader.ReadSkip(HttpVersion11.Length);
            if (reader.StartWith(CRLF) == false)
            {
                return(false);
            }

            // HTTP Second line
            reader.ReadSkip(CRLF.Length);
            int endIndex = reader.BytesBefore(DoubleCRLF);

            if (endIndex < 0)
            {
                return(false);
            }

            HttpNameValueCollection httpHeader = new HttpNameValueCollection();

            headerLength = reader.ReaderIndex + endIndex + DoubleCRLF.Length;


            while (reader.ReaderIndex < headerLength - CRLF.Length)
            {
                int keyLength = reader.BytesBefore(KvSpliter);
                if (keyLength <= 0)
                {
                    break;
                }
                string key = reader.ReadString(Encoding.ASCII, keyLength);

                reader.ReadSkip(KvSpliter.Length);
                int valueLength = reader.BytesBefore(CRLF);
                if (valueLength < 0)
                {
                    break;
                }
                string value = reader.ReadString(Encoding.ASCII, valueLength);

                if (reader.StartWith(CRLF) == false)
                {
                    break;
                }
                reader.ReadSkip(CRLF.Length);
                httpHeader.Add(key, value);
            }

            if (httpMethod != HttpMethod.GET)
            {
                contentLength = httpHeader.TryGet <int>("Content-Length");
                if (reader.Length - headerLength < contentLength)
                {
                    return(true);// 数据未完整
                }
            }


            request = new HttpRequest
            {
                LocalEndPoint  = (IPEndPoint)channel.LocalEndPoint,
                RemoteEndPoint = (IPEndPoint)channel.RemoteEndPoint,
                HttpMethod     = httpMethod,
                Headers        = httpHeader
            };

            //获取请求cookie
            string reqcookies = httpHeader.TryGet <string>("Cookie");

            if (reqcookies != null)
            {
                GenerateCookies(request, reqcookies);
            }

            string scheme = isSSL ? "https" : "http";
            string host   = httpHeader["Host"];

            if (string.IsNullOrEmpty(host) == true)
            {
                host = channel.LocalEndPoint.ToString();
            }
            request.Host = host;
            string referer = httpHeader.TryGet <string>("Referer");

            if (!string.IsNullOrEmpty(referer))
            {
                try
                {
                    request.RefererUrl = new Uri(referer);
                }
                catch { }
            }
            request.UserAgent = httpHeader.TryGet <string>("User-Agent", "");
            request.Url       = new Uri(string.Format("{0}://{1}{2}", scheme, host, path));
            request.Path      = request.Url.AbsolutePath;
            request.Query     = HttpNameValueCollection.Parse(request.Url.Query.TrimStart('?'));
            return(true);
        }
Пример #3
0
 public int BytesBefore(int length, byte value)
 {
     return(_stream.BytesBefore(length, value));
 }