예제 #1
0
        public static async Task <HttpRequest> GetIncomingRequest(Stream inputStream,
                                                                  List <byte> cache,
                                                                  Delegate_verifyHeaders proc_verify,
                                                                  CancellationToken token)
        {
            // Read Request Line
            string request = await ReadLineAsync(inputStream, cache, token);

            if (string.IsNullOrEmpty(request))
            {
                return(null);    // 表示前端已经切断通讯
            }
#if NO
            string[] tokens = request.Split(' ');
            if (tokens.Length != 3)
            {
                throw new Exception("invalid http request line");
            }
#endif
            List <string> tokens = MessageUtility.SplitFirstLine(request);
            if (tokens == null)
            {
                throw new Exception("1 invalid http request line '" + request + "'");
            }

            string method          = tokens[0].ToUpper();
            string url             = tokens[1];
            string protocolVersion = tokens[2];

            //Read Headers
            Dictionary <string, string> headers = new Dictionary <string, string>();
            string line;
            while ((line = await ReadLineAsync(inputStream, cache, token)) != null)
            {
                if (line.Equals(""))
                {
                    break;
                }

                int separator = line.IndexOf(':');
                if (separator == -1)
                {
                    throw new Exception("1 invalid http header line: " + line);
                }
                string name = line.Substring(0, separator);
                int    pos  = separator + 1;
                while ((pos < line.Length) && (line[pos] == ' '))
                {
                    pos++;
                }

                string value = line.Substring(pos, line.Length - pos);
                headers.Add(name, value);
                if (headers.Count > MAX_HEADER_LINES)
                {
                    throw new Exception("headers 行数超过配额");
                }
            }

            if (proc_verify != null)
            {
                if (proc_verify(headers) == false)
                {
                    return(null);
                }
            }

            byte[] raw_content = null;
            if (headers.ContainsKey("Content-Length"))
            {
                int totalBytes = Convert.ToInt32(headers["Content-Length"]);

                if (totalBytes >= MAX_ENTITY_BYTES)
                {
                    throw new Exception("Content-Length " + totalBytes + " 超过配额");
                }

                int    bytesLeft = totalBytes;
                byte[] bytes     = new byte[totalBytes];

                while (bytesLeft > 0)
                {
                    byte[] buffer = new byte[bytesLeft > 1024 ? 1024 : bytesLeft];

                    int nRet = 0;
                    if (cache.Count > 0)
                    {
                        nRet = Math.Min(buffer.Length, cache.Count);
                        Array.Copy(cache.ToArray(), buffer, nRet);
                        cache.RemoveRange(0, nRet);
                    }

                    int n = 0;
                    if (nRet < buffer.Length)
                    {
                        // int n = inputStream.Read(buffer, 0, buffer.Length);
                        n = await inputStream.ReadAsync(buffer, nRet, buffer.Length - nRet, token);
                    }

                    buffer.CopyTo(bytes, totalBytes - bytesLeft);

                    bytesLeft -= nRet + n;
                }

                raw_content = bytes;
            }

            return(new HttpRequest()
            {
                Method = method,
                Url = url,
                Version = protocolVersion,
                Headers = headers,
                Content = raw_content
            });
        }
예제 #2
0
        // 从 dp2library 获得响应
        private static async Task <HttpResponse> GetResponseAsync(Stream inputStream,
                                                                  CancellationToken token)
        {
            // Read Response Line
            string first_line = await ReadLineAsync0(inputStream, token);

#if NO
            // HTTP/1.1 404 Not Found
            string[] tokens = request.Split(' ');
            if (tokens.Length != 3)
            {
                throw new Exception("1 invalid http response line '" + request + "'");
            }
#endif
            List <string> tokens = MessageUtility.SplitFirstLine(first_line);
            if (tokens == null)
            {
                throw new Exception("1 invalid http response line '" + first_line + "'");
            }

            string version       = tokens[0].ToUpper();
            string status_code   = tokens[1];
            string reason_phrase = tokens[2];

            //Read Headers
            Dictionary <string, string> headers = new Dictionary <string, string>();
            string line;
            while ((line = await ReadLineAsync0(inputStream, token)) != null)
            {
                if (line.Equals(""))
                {
                    break;
                }

                int separator = line.IndexOf(':');
                if (separator == -1)
                {
                    throw new Exception("2 invalid http header line: " + line);
                }
                string name = line.Substring(0, separator);
                int    pos  = separator + 1;
                while ((pos < line.Length) && (line[pos] == ' '))
                {
                    pos++;
                }

                string value = line.Substring(pos, line.Length - pos);
                headers.Add(name, value);
            }

            byte[] raw_content = null;
            if (headers.ContainsKey("Content-Length"))
            {
                int totalBytes = Convert.ToInt32(headers["Content-Length"]);
                // TODO 观察配额
                int    bytesLeft = totalBytes;
                byte[] bytes     = new byte[totalBytes];

                while (bytesLeft > 0)
                {
                    byte[] buffer = new byte[bytesLeft > 1024 ? 1024 : bytesLeft];
                    int    n      = await inputStream.ReadAsync(buffer, 0, buffer.Length, token);

                    buffer.CopyTo(bytes, totalBytes - bytesLeft);

                    bytesLeft -= n;
                }

                raw_content = bytes;
            }

            return(new HttpResponse()
            {
                StatusCode = status_code,
                ReasonPhrase = reason_phrase,
                Headers = headers,
                Content = raw_content
            });
        }