예제 #1
0
        private const long MAX_REQUEST_SLIDING_TIMEOUT = 2 * 1000;     // 1 seconds

        public HttpRequest()
        {
            _headers = new MFToolkit.Collection.Spezialized.NameValueCollection();
        }
예제 #2
0
        private const long MAX_REQUEST_SLIDING_TIMEOUT = 2 * 1000;  // 1 seconds

        public HttpRequest()
        {
            _headers = new MFToolkit.Collection.Spezialized.NameValueCollection();
        }
예제 #3
0
        internal bool Read(Stream stream, IPEndPoint endPoint)
        {
            byte[] buffer = new byte[1024];
            RequestParserState state = RequestParserState.ReadMethod;
            string key = "";
            string value = "";
            MemoryStream ms = null;

            DateTime begin = DateTime.Now;
            DateTime lastByteReceived = begin;

            if (endPoint != null)
                UserHostAddress = endPoint.Address.ToString();

            while (true)
            {
                if (state == RequestParserState.ReadDone)
                    return true;

                int bytesRead = 0;
                int idx = 0;

#if(MF)
                // set all bytes to null byte (strings are ending with null byte in MF)
                Array.Clear(buffer, 0, buffer.Length);
#endif

                try
                {
                    bytesRead = stream.Read(buffer, 0, buffer.Length);

                    if (bytesRead > 0)
                        lastByteReceived = DateTime.Now;
                }
                catch (IOException)
                {
                    break;
                }
                catch (Exception)
                {
                    DateTime nd = DateTime.Now;
#if(MF)
                    if((nd.Ticks - lastByteReceived.Ticks) / TimeSpan.TicksPerMillisecond > MAX_REQUEST_SLIDING_TIMEOUT)
                        break;
#else
                 //   if ((nd - lastByteReceived).TotalMilliseconds > MAX_REQUEST_SLIDING_TIMEOUT)
                 //       break;
#endif

                    if (HttpMethod == "POST" && (_body == null || _body.Length < ContentLength))
                        continue;

#if(MF)
                    if((nd.Ticks - begin.Ticks) / TimeSpan.TicksPerMillisecond < MAX_REQUEST_TIMEOUT)
                        continue;
#else
                   // if ((nd - begin).TotalMilliseconds < MAX_REQUEST_TIMEOUT)
                   //     continue;
#endif

                    break;
                }

                if (bytesRead == 0)     // should never happen
                    break;

                totalBytes += bytesRead;

#if(FILELOG && !MF && !WindowsCE)
                File.AppendAllText("loghttp-" + socket.RemoteEndPoint.ToString().Replace(":", "-") + ".txt", Encoding.UTF8.GetString(buffer, 0, bytesRead) + "\r\n");
#endif

                if (totalBytes <= idx)
                    continue;

                do
                {
                    switch (state)
                    {
                        case RequestParserState.ReadMethod:
                            if (buffer[idx] != ' ')
                                HttpMethod += (char)buffer[idx++];
                            else
                            {
                                // TODO: add a allowed methods list

                                //if (HttpMethod != "POST" && HttpMethod != "GET" && HttpMethod != "OPTIONS")
                                //    throw new HttpException(HttpStatusCode.MethodNotAllowed);

                                idx++;
                                state = RequestParserState.ReadUrl;
                            }
                            break;

                        case RequestParserState.ReadUrl:
                            if (buffer[idx] == '?')
                            {
                                idx++;
                                key = "";
                                _params = new MFToolkit.Collection.Spezialized.NameValueCollection();
                                state = RequestParserState.ReadParamKey;
                            }
                            else if (buffer[idx] != ' ')
                            {
                                RawUrl += (char)buffer[idx++];
                            }
                            else
                            {
                                idx++;
                                RawUrl = HttpServerUtility.UrlDecode(RawUrl);
                                state = RequestParserState.ReadVersion;
                            }
                            break;

                        case RequestParserState.ReadParamKey:
                            if (buffer[idx] == '=')
                            {
                                idx++;
                                value = "";
                                state = RequestParserState.ReadParamValue;
                            }
                            else if (buffer[idx] == ' ')
                            {
                                idx++;
                                RawUrl = HttpServerUtility.UrlDecode(RawUrl);
                                state = RequestParserState.ReadVersion;
                            }
                            else
                            {
                                key += (char)buffer[idx++];
                            }
                            break;

                        case RequestParserState.ReadParamValue:
                            if (buffer[idx] == '&')
                            {
                                idx++;
                                key = HttpServerUtility.UrlDecode(key);
                                value = HttpServerUtility.UrlDecode(value);

                                Params[key] = (Params[key] != null ? Params[key] + ", " + value : value);

                                key = "";
                                value = "";

                                state = RequestParserState.ReadParamKey;
                            }
                            else if (buffer[idx] == ' ')
                            {
                                idx++;
                                key = HttpServerUtility.UrlDecode(key);
                                value = HttpServerUtility.UrlDecode(value);

                                Params[key] = (Params[key] != null ? Params[key] + ", " + value : value);

                                RawUrl = HttpServerUtility.UrlDecode(RawUrl);

                                state = RequestParserState.ReadVersion;
                            }
                            else
                            {
                                value += (char)buffer[idx++];
                            }
                            break;

                        case RequestParserState.ReadVersion:
                            if (buffer[idx] == '\r')
                                idx++;
                            else if (buffer[idx] != '\n')
                                HttpVersion += (char)buffer[idx++];
                            else
                            {
                                if (HttpVersion != "HTTP/1.1" && HttpVersion != "HTTP/1.0")
                                    throw new HttpException(HttpStatusCode.HttpVersionNotSupported);

                                idx++;
                                key = "";
                                Headers = new MFToolkit.Collection.Spezialized.NameValueCollection();
                                state = RequestParserState.ReadHeaderKey;
                            }
                            break;

                        case RequestParserState.ReadHeaderKey:
                            if (buffer[idx] == '\r')
                                idx++;
                            else if (buffer[idx] == '\n')
                            {
                                idx++;
                                if (HttpMethod == "POST")
                                    state = RequestParserState.ReadBody;
                                else
                                {
                                    state = RequestParserState.ReadDone;    // well, we don't really need this
                                    return true;
                                }
                            }
                            else if (buffer[idx] == ':')
                                idx++;
                            else if (buffer[idx] != ' ')
                                key += (char)buffer[idx++];
                            else
                            {
                                idx++;
                                value = "";
                                state = RequestParserState.ReadHeaderValue;
                            }
                            break;

                        case RequestParserState.ReadHeaderValue:
                            if (buffer[idx] == '\r')
                                idx++;
                            else if (buffer[idx] != '\n')
                                value += (char)buffer[idx++];
                            else
                            {
                                idx++;
                                Headers.Add(key, value);
                                key = "";
                                state = RequestParserState.ReadHeaderKey;
                            }
                            break;

                        case RequestParserState.ReadBody:

                            if (ContentLength > MAX_CONTENT_LENGTH)
                            {
                                // TODO: how can I stop the client to cancel http request
                                //throw new HttpException(HttpStatusCode.RequestEntitiyTooLarge);
                            }

                            if (ms == null)
                                ms = new MemoryStream();

                            ms.Write(buffer, idx, bytesRead - idx);
                            idx = bytesRead;
                            
                            if (ms.Length >= ContentLength)
                            {
                                _body = ms.ToArray();

                                // if using a <form/> tag with POST check if it is urlencoded or multipart boundary

                                if (ContentType.IndexOf("application/x-www-form-urlencoded") != -1)
                                {
                                    _form = new MFToolkit.Collection.Spezialized.NameValueCollection();
                                    key = "";
                                    value = null;

                                    for (int i = 0; i < _body.Length; i++)
                                    {
                                        if (_body[i] == '=')
                                            value = "";
                                        else if (_body[i] == '&')
                                        {
                                            _form.Add(key, value != null ? HttpServerUtility.UrlDecode(value) : "");
                                            key = "";
                                            value = null;
                                        }
                                        else if (value == null)
                                            key += (char)_body[i];
                                        else if (value != null)
                                            value += (char)_body[i];
                                    }

                                    if (key != null && key.Length > 0)
                                    {
                                        _form.Add(key, value != null ? HttpServerUtility.UrlDecode(value) : "");
                                    }
                                }
                                else if (ContentType != null && ContentType.Length > "multipart/form-data; boundary=".Length && ContentType.Substring(0, "multipart/form-data; boundary=".Length) == "multipart/form-data; boundary=")
                                {
                                    string boundary = ContentType.Substring("multipart/form-data; boundary=".Length);

                                    _mime = new MimeContentCollection();

                                    MimeParser mp = new MimeParser(_body, boundary);

                                    MimeContent mime = mp.GetNextContent();
                                    while (mime != null)
                                    {
                                        _mime.Add(mime.Name, mime);

                                        if (mime.Headers["Content-Disposition"] != null && mime.Headers["Content-Disposition"].IndexOf("form-data") >= 0)
                                        {
                                            if (_form == null)
                                                _form = new MFToolkit.Collection.Spezialized.NameValueCollection();

                                            _form.Add(mime.Name, (mime.Content != null && mime.Content.Length > 0 ? new string(Encoding.UTF8.GetChars(mime.Content)) : ""));
                                        }

                                        mime = mp.GetNextContent();
                                    }
                                }
                                state = RequestParserState.ReadDone;        // well, we don't really need this
                                return true;
                            }
                            break;

                        case RequestParserState.ReadDone:                   // well, we don't really need this
                            return true;

                        default:
                            //idx++;
                            break;

                    }
                }
                while (idx < bytesRead);
            }

            return false;
        }
예제 #4
0
        internal bool Read(Stream stream, IPEndPoint endPoint)
        {
            byte[]             buffer = new byte[1024];
            RequestParserState state  = RequestParserState.ReadMethod;
            string             key    = "";
            string             value  = "";
            MemoryStream       ms     = null;

            DateTime begin            = DateTime.Now;
            DateTime lastByteReceived = begin;

            if (endPoint != null)
            {
                UserHostAddress = endPoint.Address.ToString();
            }

            while (true)
            {
                if (state == RequestParserState.ReadDone)
                {
                    return(true);
                }

                int bytesRead = 0;
                int idx       = 0;

#if (MF)
                // set all bytes to null byte (strings are ending with null byte in MF)
                Array.Clear(buffer, 0, buffer.Length);
#endif

                try
                {
                    bytesRead = stream.Read(buffer, 0, buffer.Length);

                    if (bytesRead > 0)
                    {
                        lastByteReceived = DateTime.Now;
                    }
                }
                catch (IOException)
                {
                    break;
                }
                catch (Exception)
                {
                    DateTime nd = DateTime.Now;
#if (MF)
                    if ((nd.Ticks - lastByteReceived.Ticks) / TimeSpan.TicksPerMillisecond > MAX_REQUEST_SLIDING_TIMEOUT)
                    {
                        break;
                    }
#else
                    //   if ((nd - lastByteReceived).TotalMilliseconds > MAX_REQUEST_SLIDING_TIMEOUT)
                    //       break;
#endif

                    if (HttpMethod == "POST" && (_body == null || _body.Length < ContentLength))
                    {
                        continue;
                    }

#if (MF)
                    if ((nd.Ticks - begin.Ticks) / TimeSpan.TicksPerMillisecond < MAX_REQUEST_TIMEOUT)
                    {
                        continue;
                    }
#else
                    // if ((nd - begin).TotalMilliseconds < MAX_REQUEST_TIMEOUT)
                    //     continue;
#endif

                    break;
                }

                if (bytesRead == 0)     // should never happen
                {
                    break;
                }

                totalBytes += bytesRead;

#if (FILELOG && !MF && !WindowsCE)
                File.AppendAllText("loghttp-" + socket.RemoteEndPoint.ToString().Replace(":", "-") + ".txt", Encoding.UTF8.GetString(buffer, 0, bytesRead) + "\r\n");
#endif

                if (totalBytes <= idx)
                {
                    continue;
                }

                do
                {
                    switch (state)
                    {
                    case RequestParserState.ReadMethod:
                        if (buffer[idx] != ' ')
                        {
                            HttpMethod += (char)buffer[idx++];
                        }
                        else
                        {
                            // TODO: add a allowed methods list

                            //if (HttpMethod != "POST" && HttpMethod != "GET" && HttpMethod != "OPTIONS")
                            //    throw new HttpException(HttpStatusCode.MethodNotAllowed);

                            idx++;
                            state = RequestParserState.ReadUrl;
                        }
                        break;

                    case RequestParserState.ReadUrl:
                        if (buffer[idx] == '?')
                        {
                            idx++;
                            key     = "";
                            _params = new MFToolkit.Collection.Spezialized.NameValueCollection();
                            state   = RequestParserState.ReadParamKey;
                        }
                        else if (buffer[idx] != ' ')
                        {
                            RawUrl += (char)buffer[idx++];
                        }
                        else
                        {
                            idx++;
                            RawUrl = HttpServerUtility.UrlDecode(RawUrl);
                            state  = RequestParserState.ReadVersion;
                        }
                        break;

                    case RequestParserState.ReadParamKey:
                        if (buffer[idx] == '=')
                        {
                            idx++;
                            value = "";
                            state = RequestParserState.ReadParamValue;
                        }
                        else if (buffer[idx] == ' ')
                        {
                            idx++;
                            RawUrl = HttpServerUtility.UrlDecode(RawUrl);
                            state  = RequestParserState.ReadVersion;
                        }
                        else
                        {
                            key += (char)buffer[idx++];
                        }
                        break;

                    case RequestParserState.ReadParamValue:
                        if (buffer[idx] == '&')
                        {
                            idx++;
                            key   = HttpServerUtility.UrlDecode(key);
                            value = HttpServerUtility.UrlDecode(value);

                            Params[key] = (Params[key] != null ? Params[key] + ", " + value : value);

                            key   = "";
                            value = "";

                            state = RequestParserState.ReadParamKey;
                        }
                        else if (buffer[idx] == ' ')
                        {
                            idx++;
                            key   = HttpServerUtility.UrlDecode(key);
                            value = HttpServerUtility.UrlDecode(value);

                            Params[key] = (Params[key] != null ? Params[key] + ", " + value : value);

                            RawUrl = HttpServerUtility.UrlDecode(RawUrl);

                            state = RequestParserState.ReadVersion;
                        }
                        else
                        {
                            value += (char)buffer[idx++];
                        }
                        break;

                    case RequestParserState.ReadVersion:
                        if (buffer[idx] == '\r')
                        {
                            idx++;
                        }
                        else if (buffer[idx] != '\n')
                        {
                            HttpVersion += (char)buffer[idx++];
                        }
                        else
                        {
                            if (HttpVersion != "HTTP/1.1" && HttpVersion != "HTTP/1.0")
                            {
                                throw new HttpException(HttpStatusCode.HttpVersionNotSupported);
                            }

                            idx++;
                            key     = "";
                            Headers = new MFToolkit.Collection.Spezialized.NameValueCollection();
                            state   = RequestParserState.ReadHeaderKey;
                        }
                        break;

                    case RequestParserState.ReadHeaderKey:
                        if (buffer[idx] == '\r')
                        {
                            idx++;
                        }
                        else if (buffer[idx] == '\n')
                        {
                            idx++;
                            if (HttpMethod == "POST")
                            {
                                state = RequestParserState.ReadBody;
                            }
                            else
                            {
                                state = RequestParserState.ReadDone;        // well, we don't really need this
                                return(true);
                            }
                        }
                        else if (buffer[idx] == ':')
                        {
                            idx++;
                        }
                        else if (buffer[idx] != ' ')
                        {
                            key += (char)buffer[idx++];
                        }
                        else
                        {
                            idx++;
                            value = "";
                            state = RequestParserState.ReadHeaderValue;
                        }
                        break;

                    case RequestParserState.ReadHeaderValue:
                        if (buffer[idx] == '\r')
                        {
                            idx++;
                        }
                        else if (buffer[idx] != '\n')
                        {
                            value += (char)buffer[idx++];
                        }
                        else
                        {
                            idx++;
                            Headers.Add(key, value);
                            key   = "";
                            state = RequestParserState.ReadHeaderKey;
                        }
                        break;

                    case RequestParserState.ReadBody:

                        if (ContentLength > MAX_CONTENT_LENGTH)
                        {
                            // TODO: how can I stop the client to cancel http request
                            //throw new HttpException(HttpStatusCode.RequestEntitiyTooLarge);
                        }

                        if (ms == null)
                        {
                            ms = new MemoryStream();
                        }

                        ms.Write(buffer, idx, bytesRead - idx);
                        idx = bytesRead;

                        if (ms.Length >= ContentLength)
                        {
                            _body = ms.ToArray();

                            // if using a <form/> tag with POST check if it is urlencoded or multipart boundary

                            if (ContentType.IndexOf("application/x-www-form-urlencoded") != -1)
                            {
                                _form = new MFToolkit.Collection.Spezialized.NameValueCollection();
                                key   = "";
                                value = null;

                                for (int i = 0; i < _body.Length; i++)
                                {
                                    if (_body[i] == '=')
                                    {
                                        value = "";
                                    }
                                    else if (_body[i] == '&')
                                    {
                                        _form.Add(key, value != null ? HttpServerUtility.UrlDecode(value) : "");
                                        key   = "";
                                        value = null;
                                    }
                                    else if (value == null)
                                    {
                                        key += (char)_body[i];
                                    }
                                    else if (value != null)
                                    {
                                        value += (char)_body[i];
                                    }
                                }

                                if (key != null && key.Length > 0)
                                {
                                    _form.Add(key, value != null ? HttpServerUtility.UrlDecode(value) : "");
                                }
                            }
                            else if (ContentType != null && ContentType.Length > "multipart/form-data; boundary=".Length && ContentType.Substring(0, "multipart/form-data; boundary=".Length) == "multipart/form-data; boundary=")
                            {
                                string boundary = ContentType.Substring("multipart/form-data; boundary=".Length);

                                _mime = new MimeContentCollection();

                                MimeParser mp = new MimeParser(_body, boundary);

                                MimeContent mime = mp.GetNextContent();
                                while (mime != null)
                                {
                                    _mime.Add(mime.Name, mime);

                                    if (mime.Headers["Content-Disposition"] != null && mime.Headers["Content-Disposition"].IndexOf("form-data") >= 0)
                                    {
                                        if (_form == null)
                                        {
                                            _form = new MFToolkit.Collection.Spezialized.NameValueCollection();
                                        }

                                        _form.Add(mime.Name, (mime.Content != null && mime.Content.Length > 0 ? new string(Encoding.UTF8.GetChars(mime.Content)) : ""));
                                    }

                                    mime = mp.GetNextContent();
                                }
                            }
                            state = RequestParserState.ReadDone;            // well, we don't really need this
                            return(true);
                        }
                        break;

                    case RequestParserState.ReadDone:                       // well, we don't really need this
                        return(true);

                    default:
                        //idx++;
                        break;
                    }
                }while (idx < bytesRead);
            }

            return(false);
        }