?? httpuploadmodule.cs
字號:
#region License
/*
* SunriseUpload - Asp.net Upload Component
*
* Copyright (C) 2004 mic <mic4free@hotmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In case your copy of SunriseUpload does not include a copy of the license, you may find it online at
* http://www.gnu.org/copyleft/gpl.html
*
* You can find new release of this component at http://athena.9966.org/SunriseUpload .
*/
#endregion
using System;
using System.Collections;
using System.IO;
using System.Reflection;
using System.Text;
using System.Web;
using System.Xml;
namespace WUSGControl.Web.Upload
{
/// <summary>
/// The core of SunriseUpload.
/// </summary>
public class HttpUploadModule : IHttpModule
{
private DateTime beginTime = DateTime.Now;
private HttpUploadModule()
{
}
/// <summary>
/// Get value from preloaded entity body. Identified by name.
/// 解析preloadedContent中的字符 0fdde0fc-d9fb-4fb1-b45c-badac1f94a7c, 這個是在注冊按鈕時向業(yè)面注冊的一個隱藏字段
/// </summary>
/// <param name="preloadedEntityBody"></param>
/// <param name="name"></param>
/// <returns></returns>
private string AnalysePreloadedEntityBody(byte[] preloadedEntityBody, string name)
{
string val = string.Empty;
string preloadedContent = Utils.GetContext().Request.ContentEncoding.GetString(preloadedEntityBody);
//Utils.GetContext().Response.Write(preloadedContent);
//字符源樣不能被打印出來,在這里寫入文件有錯.
//Utils.2writem("preloadedContent正文已被讀取的為: " + preloadedContent);
if (preloadedContent.Length > 0)
{
int startIndex = ((preloadedContent.IndexOf(("name=\"" + name + "\"")) + 11) + name.Length);
//Utils.2writem("計算位置"+("name=\"" + name + "\""));
int endIndex = preloadedContent.IndexOf("\r\n", startIndex);
val = preloadedContent.Substring(startIndex, (endIndex - startIndex));
}
//Utils.2writem("解析val為:" + val);
return val;
}
/// <summary>
/// Event handler of request
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Application_BeginRequest(object sender, EventArgs e)
{
//Utils.writem("應用程序請求開始!");
HttpApplication application = (sender as HttpApplication);
HttpWorkerRequest workerRequest = GetWorkerRequest();
try
{
//Handle upload request only.
if (!IsUploadRequest(application.Request))
{
//Utils.2writem("httpModule第一次返回!");
return;
}
//一般第一條可以檢測過,但這一條如果不是在上傳則不可以通過
//只處理 包含 body 數(shù)據(jù) 的request
if (!workerRequest.HasEntityBody())
{
//Utils.2writem("httpModule第二次返回!");
return;
}
//Utils.2writem("Http的版本為: " + workerRequest.GetHttpVersion());
//Define a local value to store the current position of total bytes.
int currentPosition = 0;
TimeSpan span = DateTime.Now.Subtract(this.beginTime);
string contentType = application.Context.Request.ContentType.ToLower();
//Utils.2writem("contentType為"+ application.Context.Request.ContentType + "! application.Context.Request.ContentLength長度為"+application.Context.Request.ContentLength + "! 編碼為:" + application.Context.Request.ContentEncoding.ToString());
//Utils.2writem("處理過的contentType為 :" +"\r\n--" + contentType.Substring((contentType.IndexOf("boundary=") + 9)));
string b = ("\r\n--" + contentType.Substring((contentType.IndexOf("boundary=") + 9)));
byte[] boundaryData = Encoding.ASCII.GetBytes(b.ToCharArray());//數(shù)據(jù)劃分邊界
//返回與指定索引相對應的標準的http請求頭, 請求數(shù)據(jù)的長度
int FileLength = Convert.ToInt32(workerRequest.GetKnownRequestHeader(11));
//Utils.2writem("FileLength的長度為,此長度代表請求的長度,不是文件實際的長度" + FileLength.ToString());
UploadStatus uploadStatus = new UploadStatus();
application.Context.Items.Add("Sunrise_Web_Upload_FileList", new Hashtable());
//返回http請求正文已被讀取的部分, 就是桌面上的一個文本文件,
byte[] preloadedEntityBody = workerRequest.GetPreloadedEntityBody();
if (preloadedEntityBody == null)
return;
string a = Encoding.ASCII.GetString(preloadedEntityBody);
//Utils.2writem("返回http請求正文已被讀取的部分為" + a);
//已被讀取的位置要加上已讀數(shù)據(jù)實體的位置
currentPosition += preloadedEntityBody.Length;
//獲得維一ID c92b90af-f0ea-4a7c-824d-50ccde32f638
string uploadGuid = this.AnalysePreloadedEntityBody(preloadedEntityBody, "Sunrise_Web_Upload_UploadGUID");
if (uploadGuid != string.Empty)
{
application.Context.Items.Add("Sunrise_Web_Upload_UploadGUID", uploadGuid);//保存后如何訪問呢
}
bool isUploadFinished = true;
if ((FileLength > this.GetUpLoadFileLength())//文件的長度大于最大的長度
&& ((0 > span.TotalHours) || (span.TotalHours > 3)))
{
isUploadFinished = false;//上傳未結束
}
if ((0 > span.TotalHours) || (span.TotalHours > 3))
{
isUploadFinished = false;
}
string uploadFolder = this.AnalysePreloadedEntityBody(preloadedEntityBody, "Sunrise_Web_Upload_UploadFolder");
//Utils.2writem("上傳文件夾為: " + uploadFolder.ToString());
if (uploadFolder.IndexOf(@":\") < 0)
{
uploadFolder = Path.GetTempPath();//先上傳到臨時路徑中,這個可以自已定義
}
ArrayList readBody = new ArrayList();
//Utils.2writem("preloadedEntityBody is " + preloadedEntityBody.ToString() + "|boundaryData is" + boundaryData.ToString() + "uploadFolder is" + uploadFolder);
RequestStream preloadedStream = new RequestStream(preloadedEntityBody, boundaryData,
null, RequestStream.FileStatus.Close, RequestStream.ReadStatus.NoRead, uploadFolder, isUploadFinished, application.Context, string.Empty);
readBody.AddRange(preloadedStream.ReadBody);
//**********************************************************************************************************
//Set upload status. 更新上傳狀態(tài)
if (uploadGuid != string.Empty)
{
uploadStatus.FileLength = FileLength; //是兩個文件的總長度,還是一個文件的長度呢.
uploadStatus.ReceivedLength = currentPosition;
uploadStatus.FileName = preloadedStream.OriginalFileName;
uploadStatus.FileCount = ((Hashtable) application.Context.Items["Sunrise_Web_Upload_FileList"]).Count;
//if (uploadStatus.FileCount == 2)
//{
// string c = "b";//跟蹤,測試.
//}
application.Application[("_UploadGUID_" + uploadGuid)] = uploadStatus;
}
//Utils.2writem("準備進入workerRequest.IsEntireEntityBodyIsPreloaded");
//Is all data have been preload? //判斷是否還有數(shù)據(jù)可讀
//if (workerRequest.IsEntireEntityBodyIsPreloaded())//這個方法很不穩(wěn)定,有時可以有時不行,所以去掉,這樣就比較好
//{
//Utils.2writem("進入workerRequest.IsEntireEntityBodyIsPreloaded一次");
byte[] boudaryContent;
ArrayList contentBody;
//Define size of boundary.
int boundarySize = 655350;
byte[] boudaryBuffer = new byte[boundarySize];
//讀取已分好的數(shù)據(jù)塊,
//Read each data block into read body array.
while (((FileLength - currentPosition) >= boundarySize))
{
//If client is disconnected, clear all resources in use.//客戶端失去聯(lián)接時則釋放應用程序資源
if (!application.Context.Response.IsClientConnected)//客戶端超時
{
this.ReleaseRes(application);
//throw exception;
}
//Read bytes from request. 讀取客戶端請求數(shù)據(jù), 讀取數(shù)據(jù)到緩存中,返回已讀取的字節(jié)數(shù)
//讀取一個字節(jié)流
boundarySize = workerRequest.ReadEntityBody(boudaryBuffer, boudaryBuffer.Length);
currentPosition += boundarySize;//再讀取一個緩沖大小的數(shù)據(jù),所以讀取位置要往前加1
//contentBody中保存些什么東西呢
contentBody = preloadedStream.ContentBody;
////Utils.2writem("("preloadedStream.ContentBody 是"+preloadedStream.ContentBody);
if (contentBody.Count > 0)//如果已讀取了一部分則
{
////Utils.2writem("("第二次進入流!");
boudaryContent = new byte[(contentBody.Count + boudaryBuffer.Length)];
contentBody.CopyTo(boudaryContent, 0);//把內(nèi)容拷貝到boudaryContent中保存
////Utils.2writem("("boudaryContent 長度是" + boudaryContent.Length);
boudaryBuffer.CopyTo(boudaryContent, contentBody.Count);//boudaryContent
//加到文件流里面
preloadedStream = new RequestStream(boudaryContent, boundaryData,
preloadedStream.FileStream, preloadedStream.FStatus, preloadedStream.RStatus, uploadFolder, isUploadFinished, application.Context, preloadedStream.OriginalFileName);
}
else
{
////Utils.2writem("("第一次進入流");
//第一次讀取
preloadedStream = new RequestStream(boudaryBuffer, boundaryData,
preloadedStream.FileStream, preloadedStream.FStatus, preloadedStream.RStatus, uploadFolder, isUploadFinished, application.Context, preloadedStream.OriginalFileName);
}
//Append data block to read body array
readBody.AddRange(preloadedStream.ReadBody);
//Set upload status.
if (uploadGuid != string.Empty)
{
uploadStatus.ReceivedLength = currentPosition;
uploadStatus.FileName = preloadedStream.OriginalFileName;
uploadStatus.FileCount = ((Hashtable) application.Context.Items["Sunrise_Web_Upload_FileList"]).Count;
application.Application[("_UploadGUID_" + uploadGuid)] = uploadStatus;
}
}
//**********************************************************************************************************
//The rest request data //所有數(shù)據(jù)已處理完畢,查看其它數(shù)據(jù),最后一點數(shù)據(jù)單獨解析
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -