Пример #1
0
        public bool TryReadRequest(out HttpRequestData r)
        {
            r = new HttpRequestData();

            // wait for some request bytes
            if (WaitForRequestBytes() == 0)
            {
                return(false);
            }

            // reader header bytes until \r\n\r\n
            const int  MaxHeaderBytes = 32000;
            const byte CR             = ((byte)'\r');
            const byte LF             = ((byte)'\n');

            byte[] hb    = null;
            int    hbLen = -1;

            byte[] body    = null;
            int    bodyLen = 0;

            do
            {
                byte[] newBytes = ReadRequestBytes(MaxHeaderBytes);
                if (newBytes == null)
                {
                    return(false);
                }

                if (hb == null)
                {
                    hb = newBytes;
                }
                else
                {
                    int len = hb.Length + newBytes.Length;
                    if (len > MaxHeaderBytes)
                    {
                        return(false);
                    }

                    byte[] bytes = new byte[len];
                    Buffer.BlockCopy(hb, 0, bytes, 0, hb.Length);
                    Buffer.BlockCopy(newBytes, 0, bytes, hb.Length, newBytes.Length);
                    hb = bytes;
                }

                // look for \r\n\r\n in hb
                int l = hb.Length;
                for (int i = 0; i < l - 1; i++)
                {
                    if (i < l - 3 && hb[i] == CR && hb[i + 1] == LF && hb[i + 2] == CR && hb[i + 3] == LF)
                    {
                        hbLen = i + 3;
                        break;
                    }
                    else if (hb[i] == LF && hb[i + 1] == LF)
                    {
                        hbLen = i + 1;
                        break;
                    }
                }
            }while (hbLen < 0);

            // store the initial body chunk
            if (hbLen < hb.Length)
            {
                bodyLen = hb.Length - hbLen;
                body    = new byte[bodyLen];
                Buffer.BlockCopy(hb, hbLen, body, 0, bodyLen);
            }

            // convert headers to strings
            string[] headers = Encoding.UTF8.GetString(hb, 0, hbLen).Replace("\r\n", "\n").Split('\n');

            // parse request line
            string[] firstLine = headers[0].Split(' ');
            if (firstLine.Length < 2)
            {
                return(false);
            }
            r.Method = firstLine[0].Trim();
            r.Uri    = firstLine[1].Trim();

            // parse headers
            int contentLength = -1;

            for (int i = 1; i < headers.Length; i++)
            {
                string h = headers[i];
                int    j = h.IndexOf(':');
                if (j > 0)
                {
                    string k = h.Substring(0, j).Trim();
                    string v = h.Substring(j + 1).Trim();
                    r.Headers.Add(new KeyValuePair <string, string>(k, v));

                    if (string.Compare(k, "content-length", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        if (!int.TryParse(v, out contentLength))
                        {
                            contentLength = -1;
                        }
                    }
                }
            }

            // store the body from the first chunk
            if (bodyLen > 0)
            {
                r.Body.Add(body);
            }

            // read remaining body, if any
            if (contentLength > 0 && bodyLen < contentLength)
            {
                // 100 response to POST
                if (r.Method == "POST")
                {
                    WriteResponse(100, null, null, true);
                }

                while (bodyLen < contentLength)
                {
                    byte[] bytes = ReadRequestBytes(contentLength - bodyLen);
                    if (bytes == null || bytes.Length == 0)
                    {
                        return(false);
                    }
                    bodyLen += bytes.Length;
                    r.Body.Add(bytes);
                }
            }

            return(true);
        }
Пример #2
0
        public bool TryReadRequest(out HttpRequestData r) {
            r = new HttpRequestData();

            // wait for some request bytes
            if (WaitForRequestBytes() == 0) return false;

            // reader header bytes until \r\n\r\n
            const int MaxHeaderBytes = 32000;
            const byte CR = ((byte)'\r');
            const byte LF = ((byte)'\n');

            byte[] hb = null;
            int hbLen = -1;

            byte[] body = null;
            int bodyLen = 0;

            do {
                byte[] newBytes = ReadRequestBytes(MaxHeaderBytes);
                if (newBytes == null) return false;

                if (hb == null) {
                    hb = newBytes;
                }
                else {
                    int len = hb.Length + newBytes.Length;
                    if (len > MaxHeaderBytes) return false;

                    byte[] bytes = new byte[len];
                    Buffer.BlockCopy(hb, 0, bytes, 0, hb.Length);
                    Buffer.BlockCopy(newBytes, 0, bytes, hb.Length, newBytes.Length);
                    hb = bytes;
                }

                // look for \r\n\r\n in hb
                int l = hb.Length;
                for (int i = 0; i < l - 1; i++) {
                    if (i < l - 3 && hb[i] == CR && hb[i + 1] == LF && hb[i + 2] == CR && hb[i + 3] == LF) {
                        hbLen = i + 3;
                        break;
                    }
                    else if (hb[i] == LF && hb[i + 1] == LF) {
                        hbLen = i + 1;
                        break;
                    }
                }
            }
            while (hbLen < 0);

            // store the initial body chunk
            if (hbLen < hb.Length) {
                bodyLen = hb.Length - hbLen;
                body = new byte[bodyLen];
                Buffer.BlockCopy(hb, hbLen, body, 0, bodyLen);
            }

            // convert headers to strings
            string[] headers = Encoding.UTF8.GetString(hb, 0, hbLen).Replace("\r\n", "\n").Split('\n');

            // parse request line
            string[] firstLine = headers[0].Split(' ');
            if (firstLine.Length < 2) return false;
            r.Method = firstLine[0].Trim();
            r.Uri = firstLine[1].Trim();

            // parse headers
            int contentLength = -1;

            for (int i = 1; i < headers.Length; i++) {
                string h = headers[i];
                int j = h.IndexOf(':');
                if (j > 0) {
                    string k = h.Substring(0, j).Trim();
                    string v = h.Substring(j + 1).Trim();
                    r.Headers.Add(new KeyValuePair<string, string>(k, v));

                    if (string.Compare(k, "content-length", StringComparison.OrdinalIgnoreCase) == 0) {
                        if (!int.TryParse(v, out contentLength)) contentLength = -1;
                    }
                }
            }

            // store the body from the first chunk
            if (bodyLen > 0) r.Body.Add(body);

            // read remaining body, if any
            if (contentLength > 0 && bodyLen < contentLength) {
                // 100 response to POST
                if (r.Method == "POST") WriteResponse(100, null, null, true);

                while (bodyLen < contentLength) {
                    byte[] bytes = ReadRequestBytes(contentLength - bodyLen);
                    if (bytes == null || bytes.Length == 0) {
                        return false;
                    }
                    bodyLen += bytes.Length;
                    r.Body.Add(bytes);
                }
            }

            return true;
        }
Пример #3
0
        void ProcessRequest(HttpSocket s)
        {
            HttpRequestData r    = null;
            string          path = null;

            // reply to unreadable requests
            if (!s.TryReadRequest(out r))
            {
                s.WriteErrorResponse(400, "Unparsable bad request");
            }
            // deny non-GET requests
            else if (r.Method != "GET")
            {
                s.WriteErrorResponse(405, "Method other than GET");
            }
            // process special commands
            else if (TryProcessSpecialCommand(s, r.Uri))
            {
                // done
            }
            // deny requests that cannot be mapped to disk
            else if (!TryMapUri(r.Uri, out path))
            {
                s.WriteErrorResponse(404, "URI cannot be mapped to disk");
            }
            // process file requests
            else if (TryProcessFileRequest(s, r.Uri, path))
            {
                // done
            }
            // process directory requests
            else if (TryProcessDirectoryRequest(s, r.Uri, path))
            {
                // done
            }
            // process XAP requests
            else if (TryProcessXapRequest(s, path))
            {
                // done
            }
            // process XAP listing requests
            else if (TryProcessXapListingRequest(s, r.Uri, path))
            {
                // done
            }
            // process requests for assemblies contained in Chiron's localAssemblyPath
            else if (TryProcessAssemblyRequest(s, r.Uri))
            {
                // done
            }
            // process requests for .slvx files contained in Chiron's localAssemblyPath
            else if (TryProcessExternalRequest(s, r.Uri))
            {
                //done
            }
            else
            {
                // not found
                s.WriteErrorResponse(404, "Resource not found");
            }

            Chiron.Log(s.StatusCode, (r != null && r.Uri != null ? r.Uri : "[unknown]"), s.BytesSent, s.Message);
        }