супер крошечный веб-сервер в C # - PullRequest
3 голосов
/ 16 июня 2011

Я пишу супер крошечный веб-сервер для образовательных целей.

Для следующего кода, если я запрашиваю HTML-страницу, содержащую изображение, я не могу увидеть изображение в браузере. Что я делаю не так?

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;
}

Отредактировано:

    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();
    }

Для кода выше, я получаю эту ошибку в Fiddler.

Сервер не вернул правильно отформатированные заголовки HTTP. Заголовки HTTP должен быть завершен с CRLFCRLF. Они были прекращены с LFLF.

Я использую кодировку Unicode, потому что я хочу преобразовать строку в байты, и я знаю только использование кодировки.

Ответы [ 4 ]

5 голосов
/ 16 июня 2011

Ответом для JPG должен быть только заголовок HTTP, а затем содержимое JPEG, а не HTML-код вокруг него.

Что-то вроде

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

RAWJPEGDATA

Заполните XXXXXколичество байтов в Jpeg, и просто выводите необработанные данные JPEG напрямую, без какой-либо кодировки.

Используйте Fiddler или Firebug, чтобы помочь в отладке - они показывают точные запросы / ответы, отправляемые.

5 голосов
/ 16 июня 2011

Похоже, вы отправляете статус 302 Found для файлов JPEG, который предназначен для перенаправлений. Вам нужно отправить 200 OK, как вы делаете для файла HTML.

2 голосов
/ 16 июня 2011

Мне кажется, проблема в методах WriteOutputHelper и GetContentTypeHelper.

Заголовки не должны иметь \r\n\r\n, достаточно, также метод GetContentTypeHelper должен возвращать заголовок, подобный:

Content-type: image/jpeg

Не html <meta> элемент, предназначенный для (X) содержимого HTML, а не заголовок HTTP.

0 голосов
/ 16 июня 2011

Задумывались ли вы об использовании cassini, это открытый исходный код под названием проекта utildev. Вы можете определенно написать свой собственный, но вы никогда не сможете охватить все свои базы. Необычное предположение о том, что проблема заключается в том, что все типы mime не поддерживаются вашим облегченным веб-сервером.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...