Member Avatar for geekman92

Hi i need to make a BASIC HTTP server for a project using JUST TCP/IP Sockets so please don't suggest anything that would use some of C#'s higher level networking components, Thanks =).

Anyway my problem:

i have created the server and it all works so far but i haven't implemented the HTTP Headers properly, if i leave out all the headers i wrote then some browsers work fine with it (can't remember which) but when i add in the headers (and change them around trying to get it to work) it only shows part of the page or doesn't load the css file and once it just showed half of the html code!

btw i dont know if this makes a difference but i use the link tag in my main.html head to get the css file.
<link rel="stylesheet" type="text/css" href="mainStylesheet.css"/>

and before anyone asks, the html file works fine if i just run it straight on the browser! =P

Here is some of my code:

class ConnectionThread
    {
        public ConnectionThread(Socket socket)
        {
            connection = socket;
        }

        Socket connection = null;
        NetworkStream mainStream = null;
        BinaryReader inStream = null;
        BinaryWriter outStream = null;

        public void run()
        {
            mainStream = new NetworkStream(connection);

            inStream = new BinaryReader(mainStream);
            outStream = new BinaryWriter(mainStream);

            byte b = 0;
            string s = "";
            string[] requestData = null;
            string requestedPage = null;

            try
            {
                while (mainStream.DataAvailable)
                {
                    b = inStream.ReadByte();
                    s += (char)b;
                }

                requestData = s.Split('\r');

                int l = requestData.Length;

                //check to see if it got the request data (sometimes it doesn't)
                if (l > 1) 
                {
                    //get the page the browser requests
                    requestedPage = requestData[0].Split(' ')[1];

                    //calls the method which sends the browser the page to be displayed
                    theSwitch(requestedPage);
                }
                else
                {
                    //call method again to try and get the request data
                    run();
                }
            }            
            catch (Exception exp)
            {
                Console.WriteLine("Unexpected error.");
                Console.WriteLine("Error caused by: " + exp.Message);                
            }
        }

        void theSwitch(string item)
        {
            string file = null;
            char[] output = null;
            string head = null;

            try
            {
                switch (item)
                {
                    case "/":

                        file = readFile("Resources/main.html");

                        head += "HTTP/1.1 100 Continue\r\n";
                        head += String.Format("{0:ddd, dd MMM yy HH:mm:ss} GMT\r\n", DateTime.Now);
                        head += "Server: Ollie's Server v1.0\r\n";
                        head += "Cache-Control: none\r\n";
                        head += "Content-Type: text/html\r\n";
                        head += string.Format("Content-Length: {0}\r\n", file.Length);
                        head += "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\r\n";

                        Console.WriteLine(head);
                        output = (head + file).ToArray();

                        outStream.Write(output);

                        break;

                    case "Resources/mainStylesheet.css":

                        file = readFile("/mainStylesheet.css");

                        head += "HTTP/ 1.1 100 Continue\r\n";
                        head += String.Format("{0:ddd, dd MMM yy HH:mm:ss} GMT\r\n", DateTime.Now);
                        head += "Server: Ollie's Server v1.0\r\n";
                        head += "Cache-Control: none\r\n";
                        head += "Content-Type: text/css\r\n";
                        head += string.Format("Content-Length: {0}\r\n", file.Length);

                        output = (head + file).ToArray();

                        outStream.Write(file);

                        break;

                    case "Resources/favicon.ico":

                        MemoryStream ms = new MemoryStream();
                        System.Drawing.Image i = System.Drawing.Image.FromFile("Resources/favicon.gif");
                        i.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);

                        head += "HTTP/1.1 206 Partial content";
                        head += String.Format("{0:ddd, dd MMM yy HH:mm:ss} GMT\r\n", DateTime.Now);
                        head += "Server: Ollie's Server v1.0\r\n";
                        head += "Cache-Control: none\r\n";
                        head += "Content-Type: image/gif\r\n";
                        head += string.Format("Content-Length: {0}\r\n", ms.Length);

                        output = (head + ms).ToArray();

                        outStream.Write(output);

                        break;

                    default:
                        
                        Console.WriteLine("Not Found");
                        Console.WriteLine();

                        break;
                }

                inStream.Close();

                outStream.Flush();
                outStream.Close();

                mainStream.Close();

                connection.Close();

            }
            catch (Exception exp)
            {
                Console.WriteLine("Unexpected error.");
                Console.WriteLine("Error caused by: " + exp.Message);
            }
        }

        //method that returns a string of the html or css file to be sent to the browser
        private string readFile(string file)
        {
            string output = null;
            
            try
            {
                StreamReader reader = new StreamReader(file);
                while (!reader.EndOfStream)
                {
                    output += reader.ReadToEnd();
                }
            }
            catch (Exception exp)
            {
                Console.WriteLine(exp.ToString());
            }

            return output;
        }
    }
}

So i guess my question is what is the correct http headers to use here and also which headers are compulsory and which are just optional?

Edit: i would also like to use the ETag, Accept and Connection header(s) so any info you can supply on them would be greatly appreciated!

Thanks in advance! =)
Ollie

Member Avatar for geekman92

i have looked at that (and found it quite confusing) but the problem i seem to be having is with the initial line of the head:

head += "HTTP/ 1.1 100 Continue\r\n";

i don't know whether to use Continue or OK or what!

please can you help me.

Thanks
Ollie =)

Take a look at this project. What comes after the "HTTP" depends on what you are sending back. For a normal successful page I believe it's "200 OK".

Member Avatar for geekman92

okay i gathered that and i put 200 OK to start with but it didn't load the css page so is there something different i need to do to get the css page to load? i did read somewhere about using Link: but i also read that that is no longer used so i duno know!! lol

Member Avatar for geekman92

okay figured it out it was because i hadn't put a new line in between the head and the body!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.