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); } } }
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(); } }
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; } }
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; } }
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 (); }
// 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 (); }
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)); }
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); } }
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(); } }
internal static bool IsUpload(HttpWorkerRequest request) { string contentType = request.GetKnownRequestHeader(HttpWorkerRequest.HeaderContentType); return IsPost(request) && IsMultiPartFormData(contentType) && HasBoundary(contentType); }
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); } } }
public static void Log(HttpWorkerRequest worker, string uploadId) { #if DEBUG Log(" - Content-Length:" + worker.GetKnownRequestHeader(System.Web.HttpWorkerRequest.HeaderContentLength), uploadId); #endif }
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; }
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)); }
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; }
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); } }
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)); }