Пример #1
0
        private void Start()
        {
            header = FindObjects.GameLogic.GetComponent <HeaderStatus>();
            mode   = FindObjects.GameLogic.GetComponent <SubMode>();

            header.AddMode(this);
        }
Пример #2
0
        public void ReadCallback(IAsyncResult result)
        {
            HttpConnection conn = (HttpConnection)result.AsyncState;

            conn.MarkActiveOnce();
            try {
                int byteReceived = conn.ActiveSocket.EndReceive(result);

                // Remote Client Close Connection
                if (byteReceived == 0)
                {
                    conn.NaturalClose();
                    return;
                }

                ParserStatus status = ParserStatus.MOVE_NEXT_SAME_BUFFER;

                do
                {
                    switch (currentState)
                    {
                    case HTTP_HEADER:
                        status = headerParser.ProcessBuffer(conn.ConnectionBuffer, byteReceived);
                        if (status == ParserStatus.ERROR)
                        {
                            conn.Response.SendError(HttpStatusCode.BadRequest);
                            return;
                        }
                        else if (status.HasFlag(ParserStatus.MOVE_NEXT))
                        {
                            HeaderStatus header = CreateAndCheckHeader(headerParser.Content, conn, out maxContentLength);
                            if (header == HeaderStatus.ERROR)
                            {
                                conn.Response.SendError(HttpStatusCode.BadRequest);
                            }
                            else if (header == HeaderStatus.NO_CONTENT)
                            {
                                currentState = ACCEPT;
                            }
                            else if (header == HeaderStatus.CONTINUE)
                            {
                                //TODO Add 100/417 response
                            }
                            else
                            {
                                currentState = CONTENT;
                            }

                            contentParser.BufferOffset = headerParser.BufferOffset;
                        }
                        conn.ActiveSocket.BeginReceive(
                            conn.ConnectionBuffer, 0,
                            HttpConnection.BUFFER_SIZE, 0,
                            new AsyncCallback(ReadCallback), conn);
                        break;

                    case CONTENT:
                        if (maxContentLength > conn.ServerContext.ServerConfig.MaxContentSizeByte)
                        {
                            conn.Response.SendError(HttpStatusCode.RequestEntityTooLarge);
                        }

                        // IMPORTANT Identify chunked data and try to process it.
                        // =================================================
                        // The illustration of such process.
                        // We will handle it to a IChunkedRequestStream (yet to implement)
                        // This will have a built in chunk parse state machine, invoking each time
                        // when user calls method IChunkedRequestStream::ReadData.
                        //
                        // This connection will be blocked until all chunked data to be read
                        // The control will be moved to the IChunkedRequestStream, this current thread
                        // will be blocked according to "chunk parse state machine" return value:
                        //      1. ParserStatus.REQUIRE_MORE:
                        //          Thread resume, BeginReceive will be invoke to get more data.
                        //      2. ParserStatus.MOVE_NEXT:
                        //          Thread resume, Goto ACCEPT state, wait for next request.
                        //      3. ParserStatus.ERROR:
                        //          Thread resume, Send BAD_REQUEST, close the current socket.

                        status = contentParser.ProcessBuffer(conn.ConnectionBuffer, byteReceived, maxContentLength);
                        if (status.HasFlag(ParserStatus.MOVE_NEXT))
                        {
                            currentState = ACCEPT;
                        }

                        // Put the socket on recieving mode for further incoming requests
                        conn.ActiveSocket.BeginReceive(
                            conn.ConnectionBuffer, 0,
                            HttpConnection.BUFFER_SIZE, 0,
                            new AsyncCallback(ReadCallback), conn);
                        break;

                    case ACCEPT:
                        currentState     = HTTP_HEADER;
                        maxContentLength = 0;
                        headerParser.ResetParser();
                        contentParser.ResetParser();

                        CurrentRequest.RequestContentStream = new RequestStream();
                        CurrentRequest.RequestContentStream.CopyFrom(contentParser.Content);

                        conn.ServerContext.RequestDispatcher.Dispatch(
                            CurrentRequest,
                            new Response.HttpResponse(conn));
                        break;
                    }
                }while (status.HasFlag(ParserStatus.SAME_BUFFER) || currentState == ACCEPT);
            }
            catch (SocketException se) {
                //TODO May need logger here
                Console.WriteLine("{0}\r\n{1}", se.Message, se.StackTrace);
                conn.NaturalClose();
            }
            catch (Exception ex) {
                Console.WriteLine("{0}\r\n{1}", ex.Message, ex.StackTrace);
                conn.Response.SendError(HttpStatusCode.InternalServerError);
            }
        }