📄 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, 这个是在注册按钮时向业面注册的一个隐藏字段
/// </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 数据 的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());//数据划分边界
//返回与指定索引相对应的标准的http请求头, 请求数据的长度
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);
//已被读取的位置要加上已读数据实体的位置
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. 更新上传状态
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? //判断是否还有数据可读
//if (workerRequest.IsEntireEntityBodyIsPreloaded())//这个方法很不稳定,有时可以有时不行,所以去掉,这样就比较好
//{
//Utils.2writem("进入workerRequest.IsEntireEntityBodyIsPreloaded一次");
byte[] boudaryContent;
ArrayList contentBody;
//Define size of boundary.
int boundarySize = 655350;
byte[] boudaryBuffer = new byte[boundarySize];
//读取已分好的数据块,
//Read each data block into read body array.
while (((FileLength - currentPosition) >= boundarySize))
{
//If client is disconnected, clear all resources in use.//客户端失去联接时则释放应用程序资源
if (!application.Context.Response.IsClientConnected)//客户端超时
{
this.ReleaseRes(application);
//throw exception;
}
//Read bytes from request. 读取客户端请求数据, 读取数据到缓存中,返回已读取的字节数
//读取一个字节流
boundarySize = workerRequest.ReadEntityBody(boudaryBuffer, boudaryBuffer.Length);
currentPosition += boundarySize;//再读取一个缓冲大小的数据,所以读取位置要往前加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);//把内容拷贝到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 //所有数据已处理完毕,查看其它数据,最后一点数据单独解析
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -