Ejemplo n.º 1
0
        void AddHeaderVariables(HttpWorkerRequest wr)
        {
            string hname;
            string hvalue;

            // Add all known headers
            for (int i = 0; i < HttpWorkerRequest.RequestHeaderMaximum; i++)
            {
                hvalue = wr.GetKnownRequestHeader(i);
                if (null != hvalue && hvalue.Length > 0)
                {
                    hname = HttpWorkerRequest.GetKnownRequestHeaderName(i);
                    if (null != hname && hname.Length > 0)
                    {
                        Add("HTTP_" + hname.ToUpper(Helpers.InvariantCulture).Replace('-', '_'), hvalue);
                    }
                }
            }

            // Get all other headers
            string [][] unknown = wr.GetUnknownRequestHeaders();
            if (null != unknown)
            {
                for (int i = 0; i < unknown.Length; i++)
                {
                    hname = unknown [i][0];
                    if (hname == null)
                    {
                        continue;
                    }
                    hvalue = unknown [i][1];
                    Add("HTTP_" + hname.ToUpper(Helpers.InvariantCulture).Replace('-', '_'), hvalue);
                }
            }
        }
Ejemplo n.º 2
0
        string Fill(HttpWorkerRequest wr, bool standard)
        {
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < HttpWorkerRequest.RequestHeaderMaximum; i++)
            {
                string val = wr.GetKnownRequestHeader(i);
                if (val == null || val == "")
                {
                    continue;
                }
                string key = HttpWorkerRequest.GetKnownRequestHeaderName(i);
                AppendKeyValue(sb, key, val, standard);
            }
            string [][] other = wr.GetUnknownRequestHeaders();
            if (other == null)
            {
                return(sb.ToString());
            }

            for (int i = other.Length; i > 0;)
            {
                i--;
                AppendKeyValue(sb, other [i][0], other [i][1], standard);
            }

            return(sb.ToString());
        }
        protected override void InsertInfo()
        {
            HttpWorkerRequest worker_request = _request.WorkerRequest;

            if (null != worker_request)
            {
                for (int i = 0; i < HttpWorkerRequest.RequestHeaderMaximum; i++)
                {
                    string hval = worker_request.GetKnownRequestHeader(i);

                    if (hval == null || hval == "")
                    {
                        continue;
                    }

                    Add(HttpWorkerRequest.GetKnownRequestHeaderName(i), hval);
                }

                string [] [] unknown = worker_request.GetUnknownRequestHeaders();
                if (unknown != null && unknown.GetUpperBound(0) != -1)
                {
                    int top = unknown.GetUpperBound(0) + 1;

                    for (int i = 0; i < top; i++)
                    {
                        // should check if unknown [i] is not null, but MS does not.

                        Add(unknown [i] [0], unknown [i] [1]);
                    }
                }
                Protect();
            }
        }
Ejemplo n.º 4
0
		public RequestStream(HttpWorkerRequest request)
		{
			this.request = request;

			tempBuff = request.GetPreloadedEntityBody();

            _contentLength = long.Parse(request.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength));
            
            // Handle the case where GetPreloadedEntityBody is null -- e.g. Mono
			if (tempBuff == null || tempBuff.Length == 0)
			{
				isInPreloaded = false;
			}
    	}
Ejemplo n.º 5
0
        public AsyncUpload(HttpWorkerRequest wRquest)
        {
            if (wRquest == null) throw new ArgumentNullException("wRquest");
            this.uploadProcess = new UploadProcess(delegate(float f) { });
            workerRequest = wRquest;

            //当前读到的流长度
            this.preLen = workerRequest.GetPreloadedEntityBodyLength();
            //请求流的总长度
            this.totLen = workerRequest.GetTotalEntityBodyLength();
            //内容分隔符 如: -----------------------------152733254716788
            if (preLen == 0 && workerRequest.IsClientConnected() && workerRequest.HasEntityBody())
            {
                byte[] buffer = new byte[8192];
                preLen = workerRequest.ReadEntityBody(buffer, buffer.Length);
                byte[] buf = new byte[preLen];
                for (int i = 0; i < buf.Length; i++) buf[i] = buffer[i];
                this.perBodyBytes = buf;
            }
            else
                this.perBodyBytes = workerRequest.GetPreloadedEntityBody();

            this.headerBytes = this.GetBoundaryBytes(Encoding.UTF8.GetBytes(workerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentType)));
            //请求流尾部分隔符 如: -----------------------------152733254716788--
            this.contentEnd = new byte[this.headerBytes.Length + 2];
            this.headerBytes.CopyTo(this.contentEnd, 0);
            this.contentEnd[this.headerBytes.Length] = 45;
            this.contentEnd[this.headerBytes.Length + 1] = 45;

            //当前流中第一个文件分隔符的位置
            int fHeaderPosition = perBodyBytes.Indexof(fileNameHeader);
            //尝试在已读取到的流中找文件尾位置
            this.fEndPosition = perBodyBytes.Indexof(contentEnd);
            if (fHeaderPosition > -1)
            {
                //先找到文件名
                IList<byte> bufList = new List<byte>();
                int i = fHeaderPosition + fileNameHeader.Length;
                while (i < perBodyBytes.Length)
                {
                    if (perBodyBytes[i] == 34) break;
                    bufList.Add(perBodyBytes[i]);
                    i++;
                }

                this.FileName = Encoding.UTF8.GetString(bufList.ToArray());//file name
                this.fPosition = perBodyBytes.Indexof(wrapBytes, i) + 4;//当前流中此文件的开始位置
                this.FileLength = this.totLen - this.fPosition;
            }
        }
Ejemplo n.º 6
0
		static void Redirect (HttpWorkerRequest wr, string location)
		{
			string host = wr.GetKnownRequestHeader (HttpWorkerRequest.HeaderHost);
			wr.SendStatus (301, "Moved Permanently");
			wr.SendUnknownResponseHeader ("Connection", "close");
			wr.SendUnknownResponseHeader ("Date", DateTime.Now.ToUniversalTime ().ToString ("r"));
			wr.SendUnknownResponseHeader ("Location", String.Format ("{0}://{1}{2}", wr.GetProtocol(), host, location));
			Encoding enc = Encoding.ASCII;
			wr.SendUnknownResponseHeader ("Content-Type", "text/html; charset=" + enc.WebName);
			string content = String.Format (CONTENT301, host, location);
			byte [] contentBytes = enc.GetBytes (content);
			wr.SendUnknownResponseHeader ("Content-Length", contentBytes.Length.ToString ());
			wr.SendResponseFromMemory (contentBytes, contentBytes.Length);
			wr.FlushResponse (true);
			wr.CloseConnection ();
		}
Ejemplo n.º 7
0
        // Determines whether or not a given HttpWorkerRequest meets the requirements for "same-origin"
        // as called out in these two documents:
        // - http://tools.ietf.org/html/rfc6454 (Web Origin)
        // - http://tools.ietf.org/html/rfc6455 (WebSockets)
        public static bool IsSameOriginRequest(HttpWorkerRequest workerRequest) {
            string hostHeader = workerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderHost);
            if (String.IsNullOrEmpty(hostHeader)) {
                // RFC 6455 (Sec. 4.1) and RFC 2616 (Sec. 14.23) make the "Host" header mandatory
                return false;
            }

            string secWebSocketOriginHeader = workerRequest.GetUnknownRequestHeader("Origin");
            if (String.IsNullOrEmpty(secWebSocketOriginHeader)) {
                // RFC 6455 (Sec. 4.1) makes the "Origin" header mandatory for browser clients.
                // Phone apps, console clients, and similar non-browser clients aren't required to send the header,
                // but this method isn't intended for those use cases anyway, so we can fail them. (Note: it's still
                // possible for a non-browser app to send the appropriate Origin header.)
                return false;
            }

            // create URI instances from both the "Host" and the "Origin" headers
            Uri hostHeaderUri = null;
            Uri originHeaderUri = null;
            bool urisCreatedSuccessfully = Uri.TryCreate(workerRequest.GetProtocol() + "://" + hostHeader.Trim(), UriKind.Absolute, out hostHeaderUri) // RFC 2616 (Sec. 14.23): "Host" header doesn't contain the scheme, so we need to prepend
                && Uri.TryCreate(secWebSocketOriginHeader.Trim(), UriKind.Absolute, out originHeaderUri);

            if (!urisCreatedSuccessfully) {
                // construction of one of the Uri instances failed
                return false;
            }

            // RFC 6454 (Sec. 4), schemes must be normalized to lowercase. (And for WebSockets we only
            // support HTTP / HTTPS anyway.)
            if (originHeaderUri.Scheme != "http" && originHeaderUri.Scheme != "https") {
                return false;
            }

            // RFC 6454 (Sec. 5), comparisons should be ordinal. The Uri class will automatically
            // fill in the Port property using the default value for the scheme if the provided input doesn't
            // explicitly contain a port number.
            return hostHeaderUri.Scheme == originHeaderUri.Scheme
                && hostHeaderUri.Host == originHeaderUri.Host
                && hostHeaderUri.Port == originHeaderUri.Port;
        }
		string Fill (HttpWorkerRequest wr, bool standard)
		{
			StringBuilder sb = new StringBuilder ();
			
			for (int i = 0; i < HttpWorkerRequest.RequestHeaderMaximum; i++){
				string val = wr.GetKnownRequestHeader (i);
				if (val == null || val == "")
					continue;
				string key = HttpWorkerRequest.GetKnownRequestHeaderName (i);
				AppendKeyValue (sb, key, val, standard);
			}
			string [][] other = wr.GetUnknownRequestHeaders ();
			if (other == null)
				return sb.ToString ();

			for (int i = other.Length; i > 0; ){
				i--;
				AppendKeyValue (sb, other [i][0], other [i][1], standard);
			}

			return sb.ToString ();
		}
Ejemplo n.º 9
0
 private void SetByteMarkers(HttpWorkerRequest workerRequest, Encoding encoding)
 {
     var contentType = workerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentType);
     var bufferIndex = contentType.IndexOf("boundary=") + "boundary=".Length;
     var boundary = String.Concat("--", contentType.Substring(bufferIndex));
     _boundaryBytes = encoding.GetBytes(string.Concat(boundary, _lineBreak));
     //head 结尾标志 (假定!hack,不同的表单或许会不一样的)
     _endFileHeaderBytes = encoding.GetBytes(string.Concat("application/octet-stream"+_lineBreak, _lineBreak));
     _endHeaderBytes = encoding.GetBytes(string.Concat(_lineBreak, _lineBreak));
     //文件结尾标志
    // _endFileBytes = encoding.GetBytes(string.Concat(_lineBreak, boundary, "--", _lineBreak));
    _endFileBytes = encoding.GetBytes(string.Concat(_lineBreak, boundary, "--"));
    
     _lineBreakBytes = encoding.GetBytes(string.Concat(_lineBreak + boundary + _lineBreak));
 }
Ejemplo n.º 10
0
        private void context_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication app     = sender as HttpApplication;
            HttpContext     context = app.Context;


            // We need the HttpWorkerRequest of the current context to
            // process the request data. For more details about HttpWorkerRequest,
            // please follow the Readme file in the root directory.
            IServiceProvider provider = (IServiceProvider)context;

            System.Web.HttpWorkerRequest request =
                (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));

            // Get the content type of the current request.
            string contentType =
                request.GetKnownRequestHeader(
                    System.Web.HttpWorkerRequest.HeaderContentType);

            // If we could not get the content type, then skip out the module
            if (contentType == null)
            {
                return;
            }
            // If the content type is not multipart/form-data,
            //   means that there is no file upload request
            //   then skip out the moudle
            if (contentType.IndexOf("multipart/form-data") == -1)
            {
                return;
            }
            string boundary = contentType.Substring(contentType.IndexOf("boundary=") + 9);
            // Get the content length of the current request
            long contentLength = Convert.ToInt64(
                request.GetKnownRequestHeader(
                    HttpWorkerRequest.HeaderContentLength));

            // Get the data of the portion of the HTTP request body
            // that has currently been read.
            // This is the first step for us to store the upload file.
            byte[] data = request.GetPreloadedEntityBody();

            // Create an instance of the manager class which
            // help to filter the request data.
            FileUploadDataManager storeManager =
                new FileUploadDataManager(boundary);

            // Append the preloaded data.
            storeManager.AppendData(data);

            UploadStatus status = null;

            if (context.Cache[_cacheContainer] == null)
            {
                //Initialize the UploadStatus which used to
                //store the status for the client.
                status = new UploadStatus(
                    context,         // Send the current context to the status
                    // which will be used for the events.
                    contentLength    // Initialize the file length.
                    );
                // Bind a event when update the status.
                status.OnDataChanged +=
                    new UploadStatusEventHandler(status_OnDataChanged);
            }
            else
            {
                status = context.Cache[_cacheContainer] as UploadStatus;
                if (status.IsFinished)
                {
                    return;
                }
            }

            // Set the first read data length to the status class.
            if (data != null)
            {
                status.UpdateLoadedLength(data.Length);
            }

            // Get the length of the left request data.
            long leftdata = status.ContentLength - status.LoadedLength;

            // Define a custom buffer length
            int customBufferLength = Convert.ToInt32(Math.Ceiling((double)contentLength / 16));

            if (customBufferLength < 1024)
            {
                customBufferLength = 1024;
            }
            while (!request.IsEntireEntityBodyIsPreloaded() && leftdata > 0)
            {
                // Check if user abort the upload, then close the connection
                if (status.Aborted)
                {
                    // Delete the cached files.
                    foreach (UploadFile file in storeManager.FilterResult)
                    {
                        file.ClearCache();
                    }
                    request.CloseConnection();
                    return;
                }

                // If the length the remained request data
                // is less than the buffer length,
                // then set the buffer length as the remained data length.
                if (leftdata < customBufferLength)
                {
                    customBufferLength = (int)leftdata;
                }

                // Read a custom buffer length of the request data
                data = new byte[customBufferLength];
                int redlen = request.ReadEntityBody(data, customBufferLength);
                if (customBufferLength > redlen)
                {
                    data = BinaryHelper.SubData(data, 0, redlen);
                }
                // Append the left data.
                storeManager.AppendData(data);

                // Add the buffer length to the status to update the upload status
                status.UpdateLoadedLength(redlen);

                leftdata -= redlen;
            }

            // After all the data has been read,
            // save the uploaded files.
            foreach (UploadFile file in storeManager.FilterResult)
            {
                file.Save(null);
            }
        }
Ejemplo n.º 11
0
 void Application_ResolveRequestCache(object sender, EventArgs e)
 {
     wr = GetCurrentWorkerRequest();
     string contentTypeHeader = wr.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentType);
     if (contentTypeHeader != null && contentTypeHeader.ToLower().StartsWith("multipart/form-data"))
     {
         WaitForUploadToComplete();
     }
 }
Ejemplo n.º 12
0
 internal static bool IsUpload(HttpWorkerRequest request)
 {
     string contentType = request.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentType);
     return IsPost(request) && IsMultiPartFormData(contentType) && HasBoundary(contentType);
 }
Ejemplo n.º 13
0
		void AddHeaderVariables (HttpWorkerRequest wr)
		{
			string hname;
			string hvalue;

			// Add all known headers
			for (int i = 0; i < HttpWorkerRequest.RequestHeaderMaximum; i++) {
				hvalue = wr.GetKnownRequestHeader (i);
				if (null != hvalue && hvalue.Length > 0) {
					hname = HttpWorkerRequest.GetKnownRequestHeaderName (i);
					if (null != hname && hname.Length > 0)
						Add ("HTTP_" + hname.ToUpper (Helpers.InvariantCulture).Replace ('-', '_'), hvalue);
				}
			}

			// Get all other headers
			string [][] unknown = wr.GetUnknownRequestHeaders ();
			if (null != unknown) {
				for (int i = 0; i < unknown.Length; i++) {
					hname = unknown [i][0];
					if (hname == null)
						continue;
					hvalue = unknown [i][1];
					Add ("HTTP_" + hname.ToUpper (Helpers.InvariantCulture).Replace ('-', '_'), hvalue);
				}
			}
		}
Ejemplo n.º 14
0
        public static void Log(HttpWorkerRequest worker, string uploadId)
        {
#if DEBUG
            Log(" - Content-Length:" + worker.GetKnownRequestHeader(System.Web.HttpWorkerRequest.HeaderContentLength), uploadId);
#endif
        }
Ejemplo n.º 15
0
        public static Encoding GetEncodingFromHeaders(HttpWorkerRequest workerRequest)
        {
            if (workerRequest == null)
                throw new ArgumentNullException("workerRequest");

            string userAgent = workerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderUserAgent);
            if (userAgent != null && CultureInfo.InvariantCulture.CompareInfo.IsPrefix(userAgent, "UP"))
            {
                string text = workerRequest.GetUnknownRequestHeader("x-up-devcap-post-charset");
                if (!string.IsNullOrEmpty(text))
                {
                    try
                    {
                        return Encoding.GetEncoding(text);
                    }
                    catch
                    {
                    }
                }
            }
            if (!workerRequest.HasEntityBody())
            {
                return null;
            }
            string contentType = workerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentType);
            if (contentType == null)
            {
                return null;
            }
            string attributeFromHeader = GetAttributeFromHeader(contentType, "charset");
            if (attributeFromHeader == null)
            {
                return null;
            }
            Encoding result = null;
            try
            {
                result = Encoding.GetEncoding(attributeFromHeader);
            }
            catch
            {
            }
            return result;
        }
Ejemplo n.º 16
0
        public static byte[] GetMultipartBoundary(HttpWorkerRequest workerRequest)
        {
            if (workerRequest == null)
                throw new ArgumentNullException("workerRequest");

            string text = workerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentType);
            if (text == null)
                return null;

            text = GetAttributeFromHeader(text, "boundary");
            if (text == null)
                return null;

            text = "--" + text;
            return Encoding.ASCII.GetBytes(text.ToCharArray());
        }
        private void SetByteMarkers(HttpWorkerRequest workerRequest, Encoding encoding)
        {
            var contentType = workerRequest.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentType);
            var bufferIndex = contentType.IndexOf("boundary=") + "boundary=".Length;
            var boundary = String.Concat("--", contentType.Substring(bufferIndex));

            _boundaryBytes = encoding.GetBytes(string.Concat(boundary, _lineBreak));
            _endHeaderBytes = encoding.GetBytes(string.Concat(_lineBreak, _lineBreak));
            _endFileBytes = encoding.GetBytes(string.Concat(_lineBreak, boundary, "--", _lineBreak));
            _lineBreakBytes = encoding.GetBytes(string.Concat(_lineBreak + boundary + _lineBreak));
        }
Ejemplo n.º 18
0
        void loadServerVariablesCollection()
        {
            HttpWorkerRequest wr = request.WorkerRequest;

            if (loaded || (wr == null))
            {
                return;
            }

            IsReadOnly = false;

            Add("ALL_HTTP", Fill(wr, true));
            Add("ALL_RAW", Fill(wr, false));

            Add("APPL_MD_PATH", wr.GetServerVariable("APPL_MD_PATH"));
            Add("APPL_PHYSICAL_PATH", wr.GetServerVariable("APPL_PHYSICAL_PATH"));

            if (null != request.Context.User && request.Context.User.Identity.IsAuthenticated)
            {
                Add("AUTH_TYPE", request.Context.User.Identity.AuthenticationType);
                Add("AUTH_USER", request.Context.User.Identity.Name);
            }
            else
            {
                Add("AUTH_TYPE", "");
                Add("AUTH_USER", "");
            }

            Add("AUTH_PASSWORD", wr.GetServerVariable("AUTH_PASSWORD"));
            Add("LOGON_USER", wr.GetServerVariable("LOGON_USER"));
            Add("REMOTE_USER", wr.GetServerVariable("REMOTE_USER"));
            Add("CERT_COOKIE", wr.GetServerVariable("CERT_COOKIE"));
            Add("CERT_FLAGS", wr.GetServerVariable("CERT_FLAGS"));
            Add("CERT_ISSUER", wr.GetServerVariable("CERT_ISSUER"));
            Add("CERT_KEYSIZE", wr.GetServerVariable("CERT_KEYSIZE"));
            Add("CERT_SECRETKEYSIZE", wr.GetServerVariable("CERT_SECRETKEYSIZE"));
            Add("CERT_SERIALNUMBER", wr.GetServerVariable("CERT_SERIALNUMBER"));
            Add("CERT_SERVER_ISSUER", wr.GetServerVariable("CERT_SERVER_ISSUER"));
            Add("CERT_SERVER_SUBJECT", wr.GetServerVariable("CERT_SERVER_SUBJECT"));
            Add("CERT_SUBJECT", wr.GetServerVariable("CERT_SUBJECT"));

            string sTmp = wr.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength);

            if (null != sTmp)
            {
                Add("CONTENT_LENGTH", sTmp);
            }
            Add("CONTENT_TYPE", request.ContentType);

            Add("GATEWAY_INTERFACE", wr.GetServerVariable("GATEWAY_INTERFACE"));
            Add("HTTPS", wr.GetServerVariable("HTTPS"));
            Add("HTTPS_KEYSIZE", wr.GetServerVariable("HTTPS_KEYSIZE"));
            Add("HTTPS_SECRETKEYSIZE", wr.GetServerVariable("HTTPS_SECRETKEYSIZE"));
            Add("HTTPS_SERVER_ISSUER", wr.GetServerVariable("HTTPS_SERVER_ISSUER"));
            Add("HTTPS_SERVER_SUBJECT", wr.GetServerVariable("HTTPS_SERVER_SUBJECT"));
            Add("INSTANCE_ID", wr.GetServerVariable("INSTANCE_ID"));
            Add("INSTANCE_META_PATH", wr.GetServerVariable("INSTANCE_META_PATH"));
            Add("LOCAL_ADDR", wr.GetLocalAddress());
            Add("PATH_INFO", request.PathInfo);
            Add("PATH_TRANSLATED", request.PhysicalPath);
            Add("QUERY_STRING", request.QueryStringRaw);
            Add("REMOTE_ADDR", request.UserHostAddress);
            Add("REMOTE_HOST", request.UserHostName);
            Add("REMOTE_PORT", wr.GetRemotePort().ToString());
            Add("REQUEST_METHOD", request.HttpMethod);
            Add("SCRIPT_NAME", request.FilePath);
            Add("SERVER_NAME", wr.GetServerName());
            Add("SERVER_PORT", wr.GetLocalPort().ToString());
            if (wr.IsSecure())
            {
                Add("SERVER_PORT_SECURE", "1");
            }
            else
            {
                Add("SERVER_PORT_SECURE", "0");
            }
            Add("SERVER_PROTOCOL", wr.GetHttpVersion());
            Add("SERVER_SOFTWARE", wr.GetServerVariable("SERVER_SOFTWARE"));
            Add("URL", request.FilePath);

            AddHeaderVariables(wr);

            IsReadOnly = true;
            loaded     = true;
        }
Ejemplo n.º 19
0
        private void context_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication app     = sender as HttpApplication;
            HttpContext     context = app.Context;


            // 我们需要HttpWorkerRequest的当前内容来处理请求数据.
            // 要想知道HttpWorkerRequest更多更详细的内容,
            // 请参考根目录下的Readme文件.
            IServiceProvider provider = (IServiceProvider)context;

            System.Web.HttpWorkerRequest request =
                (HttpWorkerRequest)provider.GetService(typeof(HttpWorkerRequest));

            // 获取当前请求的内容类型.
            string contentType =
                request.GetKnownRequestHeader(
                    System.Web.HttpWorkerRequest.HeaderContentType);

            // 如果我们不能获取内容类型,跳过这个模块.
            if (contentType == null)
            {
                return;
            }
            //   如果内容类型不是multipart/form-data,
            //   意味着没有上传请求,
            //   就可以跳过这个模块.
            if (contentType.IndexOf("multipart/form-data") == -1)
            {
                return;
            }
            string boundary = contentType.Substring(contentType.IndexOf("boundary=") + 9);
            // 获取当前请求的内容长度.
            long contentLength = Convert.ToInt64(
                request.GetKnownRequestHeader(
                    HttpWorkerRequest.HeaderContentLength));

            // 获取HTTP请求主体的那些
            // 当前已经被读取的数据.
            // 这是我们存储上传文件的第一步.
            byte[] data = request.GetPreloadedEntityBody();

            // 创建一个管理类的实例可以
            // 帮助过滤请求数据.
            FileUploadDataManager storeManager =
                new FileUploadDataManager(boundary);

            // 添加预装载的数据.
            storeManager.AppendData(data);

            UploadStatus status = null;

            if (context.Cache[_cacheContainer] == null)
            {
                //初始化UploadStatus,
                //它被用来存储客户状态.
                status = new UploadStatus(
                    context,         //  把当前内容发送到status被事件使用
                                     //
                    contentLength    // 初始化文件长度.
                    );
                // 当更新状态时绑定事件.
                status.OnDataChanged +=
                    new UploadStatusEventHandler(status_OnDataChanged);
            }
            else
            {
                status = context.Cache[_cacheContainer] as UploadStatus;
                if (status.IsFinished)
                {
                    return;
                }
            }

            // 把首先读到的数据长度设置到status class.
            if (data != null)
            {
                status.UpdateLoadedLength(data.Length);
            }

            // 获取留下的请求数据的长度.
            long leftdata = status.ContentLength - status.LoadedLength;

            // 定义一个自定义的缓存区的长度
            int customBufferLength = Convert.ToInt32(Math.Ceiling((double)contentLength / 16));

            if (customBufferLength < 1024)
            {
                customBufferLength = 1024;
            }
            while (!request.IsEntireEntityBodyIsPreloaded() && leftdata > 0)
            {
                // 检查用户如果终止了上传,关闭连接.
                if (status.Aborted)
                {
                    // 删除缓存文件.
                    foreach (UploadFile file in storeManager.FilterResult)
                    {
                        file.ClearCache();
                    }
                    request.CloseConnection();
                    return;
                }

                // 如果剩下的请求数据小于缓
                // 冲区的长度,把缓冲区的
                // 长度设置成剩余数据的长度.
                if (leftdata < customBufferLength)
                {
                    customBufferLength = (int)leftdata;
                }

                // 读取自定义缓冲区的长度的请求数据
                data = new byte[customBufferLength];
                int redlen = request.ReadEntityBody(data, customBufferLength);
                if (customBufferLength > redlen)
                {
                    data = BinaryHelper.SubData(data, 0, redlen);
                }
                // 添加剩余数据.
                storeManager.AppendData(data);

                // 把缓冲区的长度添加到status来更新上传status.
                status.UpdateLoadedLength(redlen);

                leftdata -= redlen;
            }

            // 当所有的数据都被读取之后,
            // 保存上传文件.
            foreach (UploadFile file in storeManager.FilterResult)
            {
                file.Save(null);
            }
        }
Ejemplo n.º 20
0
        internal UploadHttpRequest(HttpContext context)
        {
            _request = context.Request;
            _worker = GetWorkerRequest(context);

            // TODO: should we silently ignore?
            if (_worker == null)
                throw new HttpException("Could not intercept worker.");

            string fileSizeHeader = _worker.GetUnknownRequestHeader("X-File-Size");

            if (string.IsNullOrEmpty(fileSizeHeader) || !long.TryParse(fileSizeHeader, out _contentLength))
                _contentLength = long.Parse(_worker.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentLength));
        }