public BrowserForm() { InitializeComponent(); this.WindowState = FormWindowState.Maximized; // Refresh this.SizeChanged += (_, e) => { WebBrowser.Refresh(); }; // Cookies WebBrowser.RequestHandler.CanSetCookie += (_, e) => { e.SetReturnValue(true); }; WebBrowser.RequestHandler.CanGetCookies += (_, e) => { e.SetReturnValue(true); }; // ContextMenu WebBrowser.ContextMenuHandler.OnBeforeContextMenu += (_, e) => { e.Model.RemoveAt(e.Model.Count - 1); e.Model.InsertItemAt(2, 26501, "Reload"); e.Model.AddItem(26502, "Copy"); e.Model.AddItem(26503, "Home"); e.Model.AddItem(26504, "Inspect"); }; WebBrowser.ContextMenuHandler.OnContextMenuCommand += (_, e) => { switch (e.CommandId) { case 26501: WebBrowser.BrowserHost.Browser.ReloadIgnoreCache(); break; case 26502: Clipboard.SetDataObject(e.Params.SelectionText); break; case 26503: LoadHomePage(); break; case 26504: ShowDevTools(); break; } }; // ResourceHandler WebBrowser.RequestHandler.GetResourceHandler += (_, e) => { CgiResource.GetResourceHandler(_, e); }; // DownloadHandler WebBrowser.DownloadHandler.OnBeforeDownload += (_, e) => { e.Callback.Continue(string.Empty, true); }; LoadHomePage(); }
private void OnProcessRequest(object sender, CfxProcessRequestEventArgs e) { var request = e.Request; var uri = new Uri(request.Url); var headers = request.GetHeaderMap().Select(x => new { Key = x[0], Value = x[1] }).ToList(); var contentRange = headers.FirstOrDefault(x => x.Key.ToLower() == "range"); if (contentRange != null) { var group = System.Text.RegularExpressions.Regex.Match(contentRange.Value, @"(?<start>\d+)-(?<end>\d*)").Groups; if (group != null) { int startPos, endPos; if (!string.IsNullOrEmpty(group["start"].Value) && int.TryParse(group["start"].Value, out startPos)) { buffStartPostition = startPos; } if (!string.IsNullOrEmpty(group["end"].Value) && int.TryParse(group["end"].Value, out endPos)) { buffEndPostition = endPos; } } isPartContent = true; } readResponseStreamOffset = 0; if (buffStartPostition.HasValue) { readResponseStreamOffset = buffStartPostition.Value; } var filePath = Uri.UnescapeDataString(uri.AbsolutePath); if (string.IsNullOrEmpty(CgiResource.Domain)) { filePath = string.Format("{0}{1}", uri.Authority, filePath); } filePath = filePath.Trim('/'); var scriptName = filePath; var physicalPath = System.IO.Path.Combine(documentRoot, filePath); if (!System.IO.File.Exists(physicalPath)) { scriptName = ""; physicalPath = documentRoot; string[] splitPath = filePath.Split('/'); foreach (string fileName in splitPath) { var realPath = System.IO.Path.Combine(physicalPath, fileName); if (!System.IO.Directory.Exists(realPath) && !System.IO.File.Exists(realPath)) { break; } scriptName += "/" + fileName; physicalPath = realPath; } } if (System.IO.Directory.Exists(physicalPath)) { var realPath = System.IO.Path.Combine(physicalPath, scriptIndex); if (System.IO.File.Exists(realPath)) { scriptName += "/" + scriptIndex; physicalPath = realPath; } } if (System.IO.File.Exists(physicalPath)) { var fileExt = System.IO.Path.GetExtension(physicalPath); if (fileExt == scriptExt) { var process = new System.Diagnostics.Process(); process.StartInfo.Arguments = physicalPath; process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; process.StartInfo.FileName = execgiPath; process.StartInfo.RedirectStandardInput = true; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.StartInfo.WorkingDirectory = documentRoot; process.StartInfo.EnvironmentVariables.Add("SERVER_SOFTWARE", "PhpWin"); process.StartInfo.EnvironmentVariables.Add("SERVER_NAME", uri.Host); process.StartInfo.EnvironmentVariables.Add("SERVER_PORT", uri.Port.ToString()); process.StartInfo.EnvironmentVariables.Add("SERVER_PROTOCOL", "HTTP/1.1"); process.StartInfo.EnvironmentVariables.Add("HTTP_HOST", uri.Host); process.StartInfo.EnvironmentVariables.Add("GATEWAY_INTERFACE", "CGI/1.1"); process.StartInfo.EnvironmentVariables.Add("REQUEST_METHOD", request.Method); if (uri.Query.Length > 1) { process.StartInfo.EnvironmentVariables.Add("QUERY_STRING", uri.Query.Substring(1)); } process.StartInfo.EnvironmentVariables.Add("REQUEST_URI", string.Format("/{0}{1}", filePath, uri.Query)); if (filePath.Length > scriptName.Length) { process.StartInfo.EnvironmentVariables.Add("PATH_INFO", filePath.Substring(scriptName.Length - 1)); } process.StartInfo.EnvironmentVariables.Add("SCRIPT_NAME", scriptName); process.StartInfo.EnvironmentVariables.Add("DOCUMENT_URI", "/" + filePath); process.StartInfo.EnvironmentVariables.Add("DOCUMENT_ROOT", documentRoot); process.StartInfo.EnvironmentVariables.Add("SCRIPT_FILENAME", physicalPath); process.StartInfo.EnvironmentVariables.Add("REDIRECT_STATUS", "200"); foreach (var item in headers) { if (item.Key == "PROXY") { continue; } if (item.Key.ToUpper() == "CONTENT-TYPE") { process.StartInfo.EnvironmentVariables.Add("CONTENT_TYPE", item.Value); } else { process.StartInfo.EnvironmentVariables.Add("HTTP_" + item.Key.Replace("-", "_").ToUpper(), item.Value); } } ulong contentLength = 0; if (request.PostData != null) { foreach (var element in request.PostData.Elements) { if (element.Type == CfxPostdataElementType.Bytes) { contentLength += element.BytesCount; } else if (element.Type == CfxPostdataElementType.File) { var fileInfo = new System.IO.FileInfo(element.File); contentLength += Convert.ToUInt64(fileInfo.Length); } } } process.StartInfo.EnvironmentVariables.Add("CONTENT_LENGTH", contentLength.ToString()); if (process.Start()) { if (request.PostData != null && contentLength > 0) { foreach (var element in request.PostData.Elements) { if (element.Type == CfxPostdataElementType.Bytes) { var buffer = new byte[element.BytesCount]; GCHandle hBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); IntPtr pBuffer = hBuffer.AddrOfPinnedObject(); var count = element.GetBytes(element.BytesCount, pBuffer); process.StandardInput.Write(Encoding.ASCII.GetChars(buffer, 0, Convert.ToInt32(count))); if (hBuffer.IsAllocated) { hBuffer.Free(); } } else if (element.Type == CfxPostdataElementType.File) { try { var buffer = System.IO.File.ReadAllBytes(element.File); process.StandardInput.BaseStream.Write(buffer, 0, Convert.ToInt32(buffer.Length)); } catch (Exception ex) { MessageBox.Show(ex.Message); e.Callback.Dispose(); e.SetReturnValue(false); return; } } } } } using (var output = new System.IO.MemoryStream()) { int read; byte[] buffer = new byte[16 * 1024]; var stream = process.StandardOutput.BaseStream; while ((read = stream.Read(buffer, 0, buffer.Length)) > 0) { output.Write(buffer, 0, read); } output.Seek(0, System.IO.SeekOrigin.Begin); var offset = 0; var reader = new System.IO.StreamReader(output); while (!reader.EndOfStream) { var readline = reader.ReadLine(); offset += readline.Length + 2; if (readline.Equals("")) { break; } var header = readline.Split(':'); if (header.Length < 2) { break; } header[1] = header[1].Trim(); if (header[0].ToUpper() == "CONTENT-TYPE") { mimeType = header[1].Split(';')[0].Trim(); } else if (header[0].ToUpper() == "STATUS") { httpStatus = int.Parse(header[1].Split(' ')[0]); } else if (header[0].ToUpper() == "LOCATION") { if (header[1].StartsWith("/")) { redirectUrl = CgiResource.GetFullUrl(header[1]); } else { redirectUrl = header[1]; } } scriptHeaders.Add(header); } var count = output.Length - offset; data = new byte[count]; output.Seek(offset, System.IO.SeekOrigin.Begin); output.Read(data, 0, Convert.ToInt32(count)); } } else { data = System.IO.File.ReadAllBytes(physicalPath); mimeType = CfxRuntime.GetMimeType(fileExt.TrimStart('.')); } e.Callback.Continue(); e.SetReturnValue(true); } else { e.Callback.Continue(); e.SetReturnValue(false); } }