简体   繁体   中英

super tiny web server in c#

I am writing a super tiny web server for educational purposes.

For the following code, if I request a html page containing an image, I cannot see the image in the browser. What am I doing wrong?

static void Main(string[] args)
{
    TcpListener listener = new TcpListener(9999);
    listener.Start();
    while (true)
    { 
        TcpClient client = listener.AcceptTcpClient();
        string request = GetRequest(client.GetStream(),
            client.ReceiveBufferSize);
        WriteOutput(request, client.GetStream());
        client.Close();
    }
}

static void WriteOutput(string request, NetworkStream output)
{
    try
    {
        string[] reqs = request.Split(' ');
        WriteOutputHelper(output, reqs[1].Substring(1));
    }
    catch (Exception)
    {
        WriteOutputHelper(output, "404.html");
    }
}

private static void WriteOutputHelper(NetworkStream output, string file)
{
    byte[] statusLine = (new System.Text.ASCIIEncoding()).
        GetBytes(GetStatusLine(file) + "\r\n\r\n");
    output.Write(statusLine, 0, statusLine.Length);
    byte[] ContentType = 
        (new System.Text.ASCIIEncoding()).GetBytes(GetContentType(file) + 
            "\r\n\r\n");
    output.Write(ContentType, 0, ContentType.Length);
    byte[] response = System.IO.File.ReadAllBytes("C:\\" + file);
    output.Write(response, 0, response.Length);
    output.Flush();
}

static string GetContentType(string fileName)
{  
    string i = "<META http-equiv=\"Content-Type\" content=\"";
    if ((fileName.IndexOf(".htm") > -1) || (fileName.IndexOf(".html") > -1))
        i = i + "text/html";
    else if (fileName.IndexOf(".jpg") > -1)
        i = i + "image/jpeg";
    i = i + ";\">";
    return i;
}

static string GetStatusLine(string fileName)
{
    string i = "HTTP/1.0 ";
    if (fileName.IndexOf("404") > -1)
        return i + "404 Not Found";
    else if (fileName.IndexOf("jpg") > -1)
        return i + "302 Found";
    return i + "200 OK";
}

static string GetRequest(NetworkStream reqStream,int bufSize)
{
    byte[] bytesFrom = new byte[10025];
    reqStream.Read(bytesFrom, 0, bufSize);
    string request = System.Text.Encoding.ASCII.GetString(bytesFrom);
    return request;
}

Edited:

    static void imageTest(NetworkStream output)
    {
        byte[] fileContent = System.IO.File.ReadAllBytes("C:\\sachin.jpg");
        string statusLine = "HTTP/1.0 200 OK" + System.Environment.NewLine;
        string contentType = "Content-type: image/jpeg" + System.Environment.NewLine;
        string contentLength = "Content-length: " + fileContent.Length + System.Environment.NewLine;
        System.Text.UnicodeEncoding coding = new UnicodeEncoding();
        byte[] headers = coding.GetBytes(statusLine + contentType + contentLength);
        output.Write(headers, 0, headers.Length);
        output.Write(fileContent, 0, fileContent.Length);
        output.Flush();
    }

For the code above, I am getting this error in fiddler.

The Server did not return properly formatted HTTP Headers. HTTP headers should be terminated with CRLFCRLF. These were terminated with LFLF.

I am using Unicode encoding because I want to convert string to bytes and I only know to use encoding.

The response for a JPG must be just the HTTP header and then the contents of the JPEG, not any HTML around it.

Something like

HTTP/1.0 200 OK
Content-type: image/jpeg
Content-length: XXXXX

RAWJPEGDATA

Fill in XXXXX with the number of bytes in the Jpeg, and just output the raw JPEG data directly, without any encoding.

Use Fiddler or Firebug to help debug -- they show the exact requests/responses being sent.

It looks like you are sending a 302 Found status for jpeg files, which is meant for redirects. You need to send 200 OK like you do for the HTML file.

I think the problem is in the WriteOutputHelper and the GetContentTypeHelper methods.

The headers should not have \\r\\n\\r\\n , one should suffice, also, the GetContentTypeHelper method should return a header like:

Content-type: image/jpeg

Not a html <meta> element which is meant for (X)HTML content, not a HTTP header.

Have you thought about using cassini, It is open source under the project title of utildev. You can definately write your own but you can never cover all your bases. An off the hip guess of what the issue is that all the mime types are not supported by your lite web server.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM