您的位置:首页 > 其它

[导入]SunriseUpload.0.9.1的源码分析(三)

2005-11-02 23:00 369 查看
在分析上传的数据时,这里用到了这样的一个函数:
/// <summary>
/// Get value from preloaded entity body. Identified by name.
/// </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);

if (preloadedContent.Length > 0)
{
int startIndex = ((preloadedContent.IndexOf(("name=\"" + name + "\"")) + 11) + name.Length);
int endIndex = preloadedContent.IndexOf("\r\n", startIndex);
val = preloadedContent.Substring(startIndex, (endIndex - startIndex));
}

return val;
}
输出的结果让我郁闷:(输出的是startIndex和endIndex及函数返回值)
11/2/2005 10:33:55 AM 5ea
11/2/2005 10:33:55 AM a
11/2/2005 10:33:55 AM :in test file.
还是先不管它的输出结果,分析代码吧。
看了半天也不明白这个函数是在干什么,测试输出结果让我很费解,这个函数在一次申请过程中调用过两次?
......输出的是startIndex和endIndex及函数返回值)
11/2/2005 10:55:09 AM 39 start
11/2/2005 10:55:09 AM 41 end
11/2/2005 10:55:09 AM 02 var
......
11/2/2005 10:55:09 AM 41
11/2/2005 10:55:09 AM 41
11/2/2005 10:55:09 AM
我试着上传一个很大的文件,然后得到以下信息:
11/2/2005 11:03:27 AM 39
11/2/2005 11:03:27 AM 43
11/2/2005 11:03:27 AM 0266

11/2/2005 11:03:28 AM 41
11/2/2005 11:03:28 AM 43
11/2/2005 11:03:28 AM 66

11/2/2005 11:04:18 AM 39
11/2/2005 11:04:18 AM 43
11/2/2005 11:04:18 AM 0212

11/2/2005 11:04:18 AM 41
11/2/2005 11:04:18 AM 43
11/2/2005 11:04:18 AM 12
可以这样分析吧:如果再一次请求过程中,提交了所有的数据,那么这个函数只被调用两次(我不知道不是上传文件都会有两次请求?)
否则会么多次请求,而且在上传没有结束之前,这个函数返回值都不为空。。。。。我也只能分析这些了。

看调用它的主函数的处理方法吧:
string uploadGuid = this.AnalysePreloadedEntityBody(preloadedEntityBody, "Sunrise_Web_Upload_UploadGUID");
if (uploadGuid != string.Empty)
{
application.Context.Items.Add("Sunrise_Web_Upload_UploadGUID", uploadGuid);
}
当然,在第一次调用this.AnalysePreloadedEntityBody的时候,返回不为空,所以会在application里添加一个Item
而里面记录的就是我们this.AnalysePreloadedEntityBody返回的值。。。。

string uploadFolder = this.AnalysePreloadedEntityBody(preloadedEntityBody, "Sunrise_Web_Upload_UploadFolder");
这里是第二次调用该方法,用于取回上传文件的临时路径。应该明白了,this.AnalysePreloadedEntityBody用来分析和读取用户上传的一些数据。这里主要是分析一些参数。

ArrayList readBody = new ArrayList();
RequestStream preloadedStream = new RequestStream(preloadedEntityBody, boundaryData,
null, RequestStream.FileStatus.Close, RequestStream.ReadStatus.NoRead, uploadFolder, isUploadFinished, application.Context, string.Empty);
这里是它的一个核心类了。看看它的构造函数!
核心在这个循环上了:
while ((preloadPosition < preloadBytes.Length))
代码太长,一下子还不好分析。。。郁闷中。。。。

没有再向下分析代码了,理由是我目前对用户提交上来的内容还不清楚,不知道应该怎样处理用户提交上来的数据。因此决定自己先把前面的内容搞清楚,于是自己写了一个HttpModule来测试。
经过这个模块的测试,终于对HTTP协议的请求有了一个全面的认识,当然这只是我自己推测的,至于对不对,那就不好说了。

先看看我写的代码:

using System;
using System.Collections;
using System.IO;
using System.Reflection;
using System.Text;
using System.Web;
using System.Xml;

namespace WebbTest
{
/// <summary>
/// Summary description for UploadTest.
/// </summary>
public class HttpModuleTest : IHttpModule
{
private System.DateTime m_startTime;

public HttpModuleTest()
{
//
// TODO: Add constructor logic here
//
m_startTime = System.DateTime.Now;
WebbSystem.TraceMsg("Construct the HttpModule.");
}

public void Dispose()
{
}

#region initialization function
/// <summary>
///
/// </summary>
/// <param name="m_application"></param>
public void Init(System.Web.HttpApplication m_application)
{
m_application.BeginRequest += new EventHandler(m_application_BeginRequest);
m_application.EndRequest += new EventHandler(m_application_EndRequest);
m_application.Error += new EventHandler(m_application_Error);
TimeSpan m_timeSpan = System.DateTime.Now.Subtract(m_startTime);
WebbSystem.TraceMsg("Init in the HttpModule."+m_timeSpan.TotalSeconds.ToString());
}
#endregion

#region Event functions
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void m_application_BeginRequest(object sender, EventArgs e)
{
#region debug message
TimeSpan m_timeSpan = System.DateTime.Now.Subtract(m_startTime);
WebbSystem.TraceMsg("m_application_BeginRequest in the HttpModule."+m_timeSpan.TotalSeconds.ToString());
#endregion

HttpApplication m_application = (sender as HttpApplication);
HttpWorkerRequest m_workerRequest = GetWorkerRequest();
//WebbSystem.TraceMsg(m_application.Request.ContentType.ToString());

byte[] m_preLoadedData = m_workerRequest.GetPreloadedEntityBody();
// Encoding targetEncoding;
// targetEncoding.EncodingName = Encoding.UTF8;
if(m_preLoadedData!=null)
{
string m_temp = Encoding.UTF8.GetString(m_preLoadedData);
WebbSystem.TraceMsg(m_temp);
}
}

private void m_application_EndRequest(object sender, EventArgs e)
{
TimeSpan m_timeSpan = System.DateTime.Now.Subtract(m_startTime);
WebbSystem.TraceMsg("m_application_EndRequest in the HttpModule."+m_timeSpan.TotalSeconds.ToString());
//Do some thing to release resouce.
HttpApplication application = (sender as HttpApplication);
application.Context.Items.Clear();

}

private void m_application_Error(object sender, EventArgs e)
{
TimeSpan m_timeSpan = System.DateTime.Now.Subtract(m_startTime);
WebbSystem.TraceMsg("Error in the HttpModule."+m_timeSpan.TotalSeconds.ToString());
//Do some thing to release resouce.
}
#endregion

#region Assistant functions
private HttpWorkerRequest GetWorkerRequest()
{
IServiceProvider provider = HttpContext.Current;
return ((HttpWorkerRequest) provider.GetService(typeof (HttpWorkerRequest)));
}
#endregion
}
}
其中WebbSystem.TraceMsg是一个向文本文件中写入记录的辅助函数,用于查看结果。最后我得到的内容:
当第一次请求的时候:
11/2/2005 2:47:16 PM m_application_BeginRequest in the HttpModule.59.28125
11/2/2005 2:47:16 PM
11/2/2005 2:47:16 PM m_application_EndRequest in the HttpModule.59.28125

点击一个button后的结果,当然我这个页面是multipart/form-data方法的
11/2/2005 2:46:30 PM m_application_BeginRequest in the HttpModule.13.71875
11/2/2005 2:46:30 PM multipart/form-data; boundary=---------------------------7d51a51e25012c
11/2/2005 2:46:30 PM -----------------------------7d51a51e25012c
Content-Disposition: form-data; name="__VIEWSTATE"

dDwtNTMwNzcxMzI0Ozs+eJ8D5aYupVVxznfxhPOz74IwJsk=
-----------------------------7d51a51e25012c
Content-Disposition: form-data; name="m_file"; filename=""
Content-Type: application/octet-stream

-----------------------------7d51a51e25012c
Content-Disposition: form-data; name="Button1"

Button
-----------------------------7d51a51e25012c--

11/2/2005 2:46:30 PM m_application_EndRequest in the HttpModule.13.71875
只要我不关闭浏览器,那么boundary的值都是一定的,也就是说
contenttype给出了请求的格式:multipart/form-data; boundary=---------------------------7d51a51e25012c
就是说:这是一个文件上传请求,用---------------------------7d51a51e25012c来分隔数据,所以上而的数据就是那样的了。
于是,在每次处理提交上来的数据的时候,一定要先处理conetntTpye然后再来通过它来处理上传的数据。最后用--来结束上传数据。
数据名与内容用 "\r\n\r\n"来分隔。好了,下面我自己来写一个函数来处理上传的数据。

文章来源:http://computer.mblogger.cn/wucountry/posts/48499.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: