The issue I'm currently facing is that I'm unable to get my C# program to write the file I want to send in the response (I'm writing the bytes of the file) and have a valid HTTP response, the browser I'm testing it with is saying ERR_INVALID_HTTP_RESPONSE
if I have appended the file to the response.
Originally I was using a HttpListener but this was requiring me to run my IDE as admin every time so I decided to move away from it and start using a TcpListener
.
This is just a simple web server that is running entirely off of C# and utilizes the TcpListener
from System.Net
. So far I've tried using the BaseStream
from the StreamWriter
to write the bytes of the file into the response.
I have been searching around to look for other ways to send a file via TCP / HTTP however it seems two things are apparent, its not brilliantly documented on how to properly do it and nobody seems to have asked the same question for this specific scenario.
So far the code that handles the response to the incoming connection is as follows.
StreamReader sr = new StreamReader(client.GetStream());
StreamWriter sw = new StreamWriter(client.GetStream());
string request = sr.ReadLine();
if (request != null) {
//byte[] testData = Encoding.UTF8.GetBytes("Test");
string[] tokens = request.Split(" ");
try {
FileInfo file = files[tokens[1]];
byte[] fileBytes = File.ReadAllBytes(file.FullName);
sw.WriteLine("HTTP/1.0 200 OK\n");
sw.BaseStream.Write(fileBytes, 0, fileBytes.Length);
sw.Flush();
} catch {
sw.WriteLine("HTTP/1.0 404 OK\n");
sw.Write("<h1>Error 404</h1><p>The file you were looking for does not exist</p>");
sw.Flush();
}
}
client.Close();
The expected result is that the browser will show the image much like you'd see from an imgur link, basically the same format as I will use to show the screenshot of the current result is the expected result.
HTTP dictates that initial lines and headers should end in CRLF
(not LF
), and that a double CRLF
should separate initial lines and headers from the response body.
Here's a super-handy quick-guide to the HTTP protocol:
https://www.jmarshall.com/easy/http/
You'll also probably need to flush your StreamWriter
before you switch from operating over the StreamWriter
to operating over it's base stream.
sw.Write("HTTP/1.0 200 OK\r\n\r\n");
sw.Flush(); // <-- HERE
sw.BaseStream.Write(fileBytes, 0, fileBytes.Length);
I'd also avoid WriteLine
as the line endings are not guaranteed to be the same across all platforms.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With