开发者

Web server: reading http request from stream

Greetings!

I've been fooling around with C# (again) and now i've stucked with s开发者_开发知识库imple HTTP web server implementation. Honestly, i don't want to get along with HTTP specification - i just need to write a very tiny (read as simple) HTTP web server. And i've encouraged this problem: client sends request to the server and then server parses it, runs some actions, builds response and sends it back to client. That seems to be obvious (for me at least).

Here's what i've got so far:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            TcpListener listener = new TcpListener(IPAddress.Any, 80);
            listener.Start();

            Socket sock = listener.AcceptSocket();

            try
            {
                Stream s = new NetworkStream(sock);
                s.ReadTimeout = 300;

                StreamReader reader = new StreamReader(s);
                StreamWriter writer = new StreamWriter(s);
                writer.AutoFlush = true;

                Console.WriteLine("Client stream read:\r\n");

                string str = "none";

                while (sock.Connected && !reader.EndOfStream && str.Length > 0) // here's where i'm stuck
                {
                    str = reader.ReadLine();
                    Console.WriteLine("{0} ({1})", str, str.Length);
                }

                Console.WriteLine("Sending response...\r\n");

                {
                    string response = "<h1>404: Page Not Found</h1>";
                    writer.WriteLine("HTTP / 1.1 404 Not Found");
                    writer.WriteLine("Content-Type: text/html; charset=utf-8");
                    writer.WriteLine("Content-Length: {0}", response.Length);
                    writer.WriteLine("\r\n{0}", response);
                }

                Console.WriteLine("Client: over\r\n");

                s.Close();
                sock.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception: {0}\r\nTrace: \r\n{1}", e.Message, e.StackTrace);
            }

            Console.ReadKey();
        }
    }
}

But i've met an "underwater stone": i'm reading request via input stream, so input data flow will be terminated when client close page in his browser (let's talk about the most obvious actions, excluding curl, w3 and other "geek-stuff").

So, the question is: how to determine request' end? E.g. when should i stop reading request data and start sending response?


Why not use HttpListener? You can have a simple HTTP server in 5 lines of code.


This Wikipedia article explains pretty succinctly about the request message format.

The request line and headers must all end with <CR><LF> (that is, a carriage return followed by a line feed). The empty line must consist of only <CR><LF> and no other whitespace. In the HTTP/1.1 protocol, all headers except Host are optional.

Basically, watch for a blank line after the headers and/or a potential message body.

According to the HTTP specification, you can use certain headers to determine if there is a message body:

The presence of a message-body in a request is signaled by the inclusion of a Content-Length or Transfer-Encoding header field in the request's message-headers.


Another option is this one: http://webserver.codeplex.com/ even if you don't want to use it, you can stole ideas because it implements the complete request lifecycle.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜