コード例 #1
0
ファイル: SocketUtility.cs プロジェクト: jdavdev/TinyWeb
        public static async void ServeHttpAsync(this Socket listener, ProcessResponse processResponseCallback, ProcessRequestBody processRequestBodyCallback = null)
        {
            var done = false;

            while (!done)
            {
                HttpRequest hreq   = null;
                Socket      socket = null;
                try
                {
                    socket = await listener.AcceptAsync();
                }
                catch (SocketException)
                {
                    socket = null;
                }
                catch (ObjectDisposedException)
                {
                    socket = null;
                }
                if (null != socket)
                {
                    var newHreq = await socket.ReceiveHttpRequestAsync();

                    if (null != newHreq)
                    {
                        hreq = newHreq;
                    }
                    else
                    {
                        done = true;
                    }
                    if (null != hreq)
                    {
                        var hres = new HttpResponse(hreq, socket);
                        processResponseCallback(hreq, hres);
                        if (!hres.IsClosed)
                        {
                            if (!hres.HasSentHeaders)
                            {
                                hres.SendHeaders();
                            }
                            try
                            {
                                hres.SendEndChunk();
                            }
                            catch { }

                            if (!hres.HasHeader("Connection") && !hres.IsKeepAlive)
                            {
                                hres.Close();
                                done = true;
                            }
                        }
                        else
                        {
                            done = true;
                        }
                    }
                    else
                    {
                        done = true;
                    }
                }
                else
                {
                    done = true;
                }
            }
        }
コード例 #2
0
ファイル: SocketUtility.cs プロジェクト: jdavdev/TinyWeb
        /// <summary>
        /// Synchronously and minimally processes an http request on the specified socket. Reads the data, including any headers and the request body, if present, and then leaves the socket in a state ready to send a response.
        /// </summary>
        /// <param name="socket">The socket connected to the remote client that made the request</param>
        /// <param name="requestBodyCallback">An optional callback that will substitute large data handling in the request body. If null, the data sent with the request will be available in the RequestBody field.</param>
        /// <returns>The info associated with the request.</returns>
        /// <remarks>You're virtually always better off using the asynchronous method. However, if you're already spawning threads for handling connections, this might be a decent way to put some to work. However, the asynchronous methods may still provide better performance in that scenario. Benchmark if you care. If you care about performance and scalability, this isn't the right method server for you anyway.</remarks>
        public static HttpRequest ReceiveHttpRequest(this Socket socket, ProcessRequestBody requestBodyCallback = null)
        {
            StringBuilder reqheaders = null;
            Stream        body       = null;
            int           bytesRead  = -2;

            byte[] recv = new byte[1024];
            bytesRead = socket.Receive(recv, 0, recv.Length, 0);
            if (0 != bytesRead)
            {
                reqheaders = new StringBuilder();
                string s = Encoding.ASCII.GetString(recv, 0, bytesRead);
                reqheaders.Append(s);
                int i = reqheaders.ToString().IndexOf("\r\n\r\n");
                while (0 > i && 0 != bytesRead)
                {
                    bytesRead = socket.Receive(recv, 0, recv.Length, 0);
                    if (0 != bytesRead)
                    {
                        s = Encoding.ASCII.GetString(recv, 0, bytesRead);
                        reqheaders.Append(s);
                        i = reqheaders.ToString().IndexOf("\r\n\r\n");
                    }
                }
                if (0 > i)
                {
                    throw new Exception("Bad Request");
                }
                long rr = 0;
                if (i + 4 < reqheaders.Length)
                {
                    byte[] data = Encoding.ASCII.GetBytes(reqheaders.ToString(i + 4, reqheaders.Length - (i + 4)));
                    rr = data.Length;
                    // process request body data
                    if (null != requestBodyCallback)
                    {
                        requestBodyCallback(socket, reqheaders.ToString(), data);
                    }
                    else
                    {
                        if (null == body)
                        {
                            body = new MemoryStream();
                        }
                        body.Write(data, 0, data.Length);
                    }
                }
                int ci = reqheaders.ToString().IndexOf("Content-Length:", StringComparison.InvariantCultureIgnoreCase);
                if (-1 < ci)
                {
                    // we have more post data
                    ci += 15;
                    while (ci < reqheaders.Length && char.IsWhiteSpace(reqheaders[ci]))
                    {
                        ++ci;
                    }
                    long cl = 0;
                    while (ci < reqheaders.Length && char.IsDigit(reqheaders[ci]))
                    {
                        cl *= 10;
                        cl += reqheaders[ci] - '0';
                        ++ci;
                    }
                    if ('\r' != reqheaders[ci] && '\n' != reqheaders[ci])
                    {
                        throw new Exception("Bad Request");
                    }
                    long l = rr;
                    while (l < cl)
                    {
                        bytesRead = socket.Receive(recv, 0, recv.Length, 0);
                        if (0 < bytesRead)
                        {
                            l += bytesRead;
                            byte[] data = new byte[bytesRead];
                            Buffer.BlockCopy(recv, 0, data, 0, bytesRead);
                            // process request body data
                            if (null != requestBodyCallback)
                            {
                                requestBodyCallback(socket, reqheaders.ToString(), data);
                            }
                            else
                            {
                                if (null == body)
                                {
                                    body = new MemoryStream();
                                }
                                body.Write(data, 0, data.Length);
                            }
                        }
                    }
                }
                reqheaders.Length = i + 2;
                return(new HttpRequest(reqheaders.ToString(), body));
            }
            socket.Close();
            return(null);
        }