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
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.