using System;
using System.IO;
using System.Net;
using System.Collections.Generic;
using System.Text;
using IReaper.Properties;
using ICSharpCode.SharpZipLib.Zip;
namespace IReaper.Initializer{
/// <summary>
/// User HTTP Conditional Get to get latest info.xml
/// </summary>
public class CheckInfoXMLTask : AbstractInitTask
{
public static string IndexPath = null;
public static string InfoXmlPath = null;
private static string _IndexTmpPath = null;
static CheckInfoXMLTask()
{
IndexPath = Path.Combine(AppDataFolder, IndexFileName);
InfoXmlPath = Path.Combine(AppDataFolder, DataFileName);
_IndexTmpPath = IndexPath + ".tmp";
}
private static DateTime MinValue = new DateTime(1970, 1, 1);
HttpWebRequest request;
HttpWebResponse response;
FileStream fsStream;
protected override void JobContent()
{
try
{
//set message
this.InitManager.SetMessage(StringResources.Checking);
if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{ return; }
DateTime localDate = this.LastModifiedDate();
this.ConditionalGet(localDate);
}
catch (Exception e)
{
InitManager.SetException(e);
}
finally
{
//make sure the resources are closed.
if (response != null)
response.Close();
if (fsStream != null)
fsStream.Close();
}
}
/// <summary>
/// Check the last modified date of info.xml
/// </summary>
/// <returns>last modified date</returns>
private DateTime LastModifiedDate()
{
//get file information
FileInfo fileInfo = new FileInfo(IndexPath);
DateTime LocalTime;
if (!fileInfo.Exists)//if file is not found, set the DateTime.MinValue as time
{
LocalTime = MinValue;
}
else
LocalTime = fileInfo.LastWriteTime;//otherwise,get the datetime
return LocalTime;
}
/// <summary>
/// Use conditional get to download info.xml
/// </summary>
/// <param name="LocalDate">last modified date of local info.xml</param>
private void ConditionalGet(DateTime LocalDate)
{
string path = Settings.Default.PathBase + IndexFileName;
//create HttpWebRequest
request = (HttpWebRequest)WebRequest.Create(path);
request.IfModifiedSince = LocalDate;
request.Method = WebRequestMethods.Http.Get;
//try to get response
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (Exception e) //For some reason the HttpWebResponse class throws an exception on 3xx responses
{
WebException we = e as WebException;
if ( we != null && we.Response != null)
{
response = (HttpWebResponse)we.Response;
}
else
{
throw;
}
}
//if responseCode is 304,which means no need to update.
if (response.StatusCode == HttpStatusCode.NotModified)//check if not modified
{
response.Close();
this.resultObj = "NotModified";
return;
}
//if means there is something mistake.
else if (response.ContentLength == -1)
{
throw new ApplicationException(StringResources.ERROR_GetInfoXML + response.StatusDescription + "(" + response.StatusCode.ToString() + ")");
}
else if (response.ContentType == "application/x-zip-compressed") //the index.zip is updated since last time
{
//set message
this.InitManager.SetMessage(StringResources.BeginDownload + DataFileName);
//get last modified date of
DateTime LastModified = response.LastModified;
//get the network stream
Stream netStream = response.GetResponseStream();
//create the file local stream
try
{
fsStream = new FileStream(_IndexTmpPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None);
//set the creation time as minValue in case the download is interrputed.
//download
long length = response.ContentLength;
byte[] buffer = new byte[1024];
fsStream.SetLength(response.ContentLength);
int iRead = 0;
while (fsStream.Position < length)
{
iRead = netStream.Read(buffer, 0, 1024);
fsStream.Write(buffer, 0, iRead);
//set message
int percentage = (int)(fsStream.Position * 100 / length);
this.InitManager.SetMessage(StringResources.Downloading + percentage.ToString() + "%");
}
// Unpackage
fsStream.Position = 0;
UnpackageIndex(fsStream);
fsStream.Close();
}
catch
{
//close the stream to set the last write time
fsStream.Close();
throw;
}
finally
{
netStream.Close();
}
File.Delete(IndexPath);
File.Move(_IndexTmpPath, IndexPath);
File.SetLastWriteTime(IndexPath, LastModified);
//set message
this.resultObj = "Modified";
// Extract this zip file to l
}
}
// extract the index package file.
private void UnpackageIndex(FileStream zipStrm)
{
ZipInputStream zipInput = new ZipInputStream(zipStrm);
zipInput.IsStreamOwner = false;
byte[] buffer = new byte[4096];
ZipEntry entry = null;
while ((entry = zipInput.GetNextEntry()) != null)
{
long length = zipInput.Length;
long iRead = 0;
using (FileStream output = new FileStream(Path.Combine(AppDataFolder, entry.Name), FileMode.Create, FileAccess.Write))
{
while (iRead < length)
{
int len = zipInput.Read(buffer, 0, buffer.Length);
output.Write(buffer, 0, len);
iRead += len;
}
output.Close();
}
}
}
}
}
|