The idea is simple, i am creating a service where user can put the direct link of a file that is being hosted on another website and my program will open a stream to that remote server and start reading the file in bytes and then return each readed byte to the user.
so far i managed to get that working and here is my code
public void Index()
{
//Create a stream for the file
Stream stream = null;
//This controls how many bytes to read at a time and send to the client
int bytesToRead = 10000; //10000
// Buffer to read bytes in chunk size specified above
byte[] buffer = new Byte[bytesToRead];
// The number of bytes read
try
{
//Create a WebRequest to get the file
HttpWebRequest fileReq = (HttpWebRequest)HttpWebRequest.Create("http://SOME-OTHER-SERVER.com/File.rar");
//Create a response for this request
HttpWebResponse fileResp = (HttpWebResponse)fileReq.GetResponse();
if (fileReq.ContentLength > 0)
fileResp.ContentLength = fileReq.ContentLength;
//Get the Stream returned from the response
stream = fileResp.GetResponseStream();
// prepare the response to the client. resp is the client Response
var resp = HttpContext.Response;
//Indicate the type of data being sent
resp.ContentType = "application/octet-stream";
//Name the file
resp.AddHeader("Content-Disposition", "attachment; filename=\"" + "fle.rar" + "\"");
resp.AddHeader("Content-Length", (fileResp.ContentLength).ToString());
int length;
do
{
// Verify that the client is connected.
if (resp.IsClientConnected)
{
// Read data into the buffer.
length = stream.Read(buffer, 0, bytesToRead);
// and write it out to the response's output stream
resp.OutputStream.Write(buffer, 0, length);
// Flush the data
resp.Flush();
//Clear the buffer
buffer = new Byte[bytesToRead];
}
else
{
// cancel the download if client has disconnected
length = -1;
}
} while (length > 0); //Repeat until no data is read
}
finally
{
if (stream != null)
{
//Close the input stream
stream.Close();
}
}
}
When i go to my page it downloads perfectly but the problem is if i stopped the download it won't resume again.
I searched for that issue and figured out that there is a header "Accept-Ranges" that must be defined in the connection in order to support resume.
so i added that header but didn't work.
Handling Range Requests is a little bit more complicated than that. In general you need to handle
Range
andIf-Range
headers in request and serve proper 206 Partial Content responses withContent-Range
,Date
andETag
orContent-Location
headers.The article Range Requests in ASP.NET MVC – RangeFileResult describes in details how to create an ASP.NET MVC
ActionResult
with Range Request support.In your case you will also have to check if the other side (the one for which you use
fileReq
) support Range Request. If yes than you can request just the needed part (and preferably cache it somewhere locally), but if not than you need to get the entire file and seek to proper locations (in that situation you defintely want to have a local caching scenario).