.htaccess editor: start / stop ape debugger

This commit is contained in:
Ruslan Keba 2013-03-26 18:06:40 +02:00
parent 19b52f025c
commit 7cc5207bfb
6 changed files with 255 additions and 142 deletions

View file

@ -1369,20 +1369,11 @@ UL.ActionButtons LI
width:100px;
}
table#toolbar
{
width: 100%;
display: none;
}
.pnlControl input.NormalTextBox
{
width: 300px;
}
.toolbar-space
{
width: 80%;
}
.disabled
{
width:20px;
@ -1391,12 +1382,6 @@ table#toolbar
border:medium none;
}
.toolbar-button
{
padding: 0 1px;
cursor: pointer;
white-space: nowrap;
}
.enabled
{
width:20px;
@ -1405,10 +1390,14 @@ table#toolbar
border:medium none;
}
p.warningText {font-size:14px; color:Red; text-align:center;}
p.warningText {
font-size:14px;
color:Red;
text-align:center;
}
.Hidden
{
display: none;
}
}

View file

@ -117,8 +117,11 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="btnApeDebugger.Text" xml:space="preserve">
<value>Start Debug</value>
<data name="btnApeDebuggerStart.Text" xml:space="preserve">
<value>Start Debugging</value>
</data>
<data name="btnApeDebuggerStop.Text" xml:space="preserve">
<value>Stop Debugging</value>
</data>
<data name="btnCancel.Text" xml:space="preserve">
<value>Cancel</value>
@ -130,6 +133,6 @@
<value>Update</value>
</data>
<data name="lblFolderName.Text" xml:space="preserve">
<value>Folder Path:</value>
<value>.htaccess path: </value>
</data>
</root>

View file

@ -5,82 +5,57 @@
<script type="text/javascript" src="/JavaScript/jquery.min.js?v=1.4.4"></script>
<script type="text/javascript" src="/JavaScript/codemirror/codemirror.js"></script>
<script type="text/javascript" src="/JavaScript/codemirror/htaccess.js"></script>
<script type="text/javascript">
function pageLoad() {
$('input:hidden').each(function (index, el) {
if ($(this).attr('id').indexOf('ApeDebuggerUrl') >= 0) {
if (this.value) {
$('#toolbar-start-debug').show();
}
}
});
};
function openDebugWindow() {
$('input:hidden').each(function (index, el) {
if ($(this).attr('id').indexOf('ApeDebuggerUrl') >= 0) {
if (this.value) {
window.open(this.value);
}
}
});
return false;
}
</script>
<style>
<style type="text/css">
.CodeMirror {
border: 1px solid #444;
padding: 2px;
font-family: Consolas, monospace;
font-size: 13px;
font-size: 14px;
}
</style>
<div class="FormBody">
<table cellspacing="0" cellpadding="0" width="100%">
<tr>
<td>
<table cellspacing="0" cellpadding="5" width="100%">
<tr>
<td class="SubHead">
<asp:Label ID="lblFolderName" runat="server" meta:resourcekey="lblFolderName" Text="Folder Path:"></asp:Label>
</td>
<td class="NormalBold">
<uc1:FileLookup id="folderPath" runat="server" Width="400">
</uc1:FileLookup>
<asp:HiddenField ID="contentPath" runat="server" />
<asp:HiddenField ID="ApeDebuggerUrl" runat="server" />
</td>
</tr>
<tr>
<td colspan="2">
<table id="toolbar">
<tr>
<td>
<asp:Button ID="btnApeDebug" runat="server" Text="Start Debug" meta:resourcekey="btnApeDebugger"
CssClass="toolbar-button" OnClick="btnApeDebug_Click" />
</td>
<td>
<button id="toolbar-start-debug" cssclass="toolbar-button" style="display: none;"
onclick="return openDebugWindow();">
Open&nbsp;Debug&nbsp;window</button>
</td>
<td class="toolbar-space">&nbsp;</td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="2">
<asp:TextBox ID="htaccessContent" runat="server" TextMode="MultiLine" class="CodeEditor"></asp:TextBox>
</td>
</tr>
</table>
</td>
</tr>
</table>
<table cellspacing="0" cellpadding="5" width="100%">
<tr>
<td class="SubHead" style="white-space: nowrap;">
<asp:Label ID="lblFolderName" runat="server" meta:resourcekey="lblFolderName"></asp:Label>
</td>
<td class="NormalBold" style="white-space: nowrap;">
<asp:Label runat="server" ID="LabelWebSiteName"></asp:Label>
<uc1:FileLookup id="folderPath" runat="server" Width="400">
</uc1:FileLookup>
<asp:HiddenField ID="contentPath" runat="server" />
<asp:HiddenField ID="DebuggerUrlField" runat="server" />
</td>
<td style="width: 40%">
<asp:Button ID="ButtonDebuggerStart" runat="server" Text="Start Debug" meta:resourcekey="btnApeDebuggerStart"
CssClass="Button1" OnClick="DebugStartClick" />
<asp:Button ID="ButtonDebuggerStop" runat="server" Text="Start Debug" meta:resourcekey="btnApeDebuggerStop"
CssClass="Button1" OnClick="DebugStopClick" />
</td>
</tr>
</table>
<table id="toolbar" width="100%">
<tr>
<td>
</td>
<td style="width: 90%">
<asp:Label runat="server" ID="ContainerLinkDebuggingPage" Visible="False">
Open debugging page: <asp:HyperLink runat="server" ID="LinkDebuggingPage" Target="ape-debugging-page"></asp:HyperLink>
</asp:Label>
</td>
</tr>
</table>
<asp:Panel runat="server" ID="DebuggerFramePanel" Visible="False">
<iframe runat="server" ID="DebuggerFrame" width="100%" height="400px"></iframe>
</asp:Panel>
<asp:TextBox ID="htaccessContent" runat="server" TextMode="MultiLine" class="CodeEditor"></asp:TextBox>
</div>
<div class="FormFooter">
<asp:Button ID="btnUpdate" runat="server" Text="Update" meta:resourcekey="btnUpdate"
CssClass="Button1" OnClick="btnUpdate_Click" />

View file

@ -31,6 +31,7 @@ using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Security;
@ -65,22 +66,30 @@ namespace WebsitePanel.Portal
{
// read httpd.conf
folder = ES.Services.WebServers.GetHeliconApeHttpdFolder(int.Parse(spaceId));
btnApeDebug.Visible = false;
ButtonDebuggerStart.Visible = false;
ButtonDebuggerStop.Visible = false;
}
else
{
// read web site
WebSite site = ES.Services.WebServers.GetWebSite(PanelRequest.ItemID);
WebSite site = GetWebSite();
if (site == null)
{
RedirectToBrowsePage();
return;
}
LabelWebSiteName.Text = site.Name;
folderPath.RootFolder = site.ContentPath;
folderPath.PackageId = site.PackageId;
htaccessContent.Text = "# Helicon Ape\n";
ButtonDebuggerStart.Visible = true;
ButtonDebuggerStop.Visible = false;
if (String.IsNullOrEmpty(PanelRequest.Name))
return;
@ -102,14 +111,16 @@ namespace WebsitePanel.Portal
{
htaccessContent.Text = "# Helicon Ape\n";
}
ApeDebuggerUrl.Value = "";
/*
DebuggerUrlField.Value = "";
if ( RE_APE_DEBUGGER_ENABLED.IsMatch(htaccessContent.Text) )
{
btnApeDebug.Text = "Stop Debug";
GetApeDebuggerUrl();
btnApeDebug.Text = (string)GetLocalResourceObject("btnApeDebuggerStop.Text");
GetDebuggerUrl();
}
*/
}
@ -123,19 +134,6 @@ namespace WebsitePanel.Portal
string spaceId = Request.QueryString["SpaceID"];
if (RE_APE_DEBUGGER_ENABLED.IsMatch(htaccessContent.Text))
{
btnApeDebug.Text = "Stop Debug";
GetApeDebuggerUrl();
}
else
if (RE_APE_DEBUGGER_DISABLED.IsMatch(htaccessContent.Text))
{
btnApeDebug.Text = "Start Debug";
GetApeDebuggerUrl();
}
try
{
if (folder.Path == HtaccessFolder.HTTPD_CONF_FILE && !string.IsNullOrEmpty(spaceId))
@ -177,67 +175,159 @@ namespace WebsitePanel.Portal
protected readonly Regex RE_APE_DEBUGGER_ENABLED = new Regex(@"^[ \t]*(SetEnv\s+mod_developer\s+secure-key-([\d]+))", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
protected readonly Regex RE_APE_DEBUGGER_DISABLED = new Regex(@"^[ \t]*#[ \t]*(SetEnv\s+mod_developer\s+secure-key-([\d]+))", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
protected string ApeDebuggerSecureKey = "";
//protected string ApeDebuggerUrl = "";
protected string DebuggerSecureKey = "";
protected string DebuggerSessionId = "";
protected string DebuggerUrl = "";
protected string DebuggingPageUrl = "";
protected void btnApeDebug_Click(object sender, EventArgs e)
protected void DebugStartClick(object sender, EventArgs e)
{
var code = htaccessContent.Text;
if ( RE_APE_DEBUGGER_DISABLED.IsMatch(code) )
{
// already disabled, enable it!
ApeDebuggerSecureKey = RE_APE_DEBUGGER_DISABLED.Match(code).Groups[2].Value;
DebuggerSecureKey = RE_APE_DEBUGGER_DISABLED.Match(code).Groups[2].Value;
code = RE_APE_DEBUGGER_DISABLED.Replace(code, "$1");
btnApeDebug.Text = "Stop Debug";
}
else if ( RE_APE_DEBUGGER_ENABLED.IsMatch(code) )
{
// alerdy enable, disable it!
ApeDebuggerSecureKey = "";
code = RE_APE_DEBUGGER_ENABLED.Replace(code, "# $1");
btnApeDebug.Text = "Start Debug";
}
else
{
ApeDebuggerSecureKey = new Random().Next(100000000, 999999999).ToString();
code = code + "\nSetEnv mod_developer secure-key-" + ApeDebuggerSecureKey +"\n";
btnApeDebug.Text = "Stop Debug";
DebuggerSecureKey = new Random().Next(100000000, 999999999).ToString(CultureInfo.InvariantCulture);
code = code + "\nSetEnv mod_developer secure-key-" + DebuggerSecureKey +"\n";
}
htaccessContent.Text = code;
SaveFolder();
GetApeDebuggerUrl();
StartDebugger();
}
private void GetApeDebuggerUrl()
protected void DebugStopClick(object sender, EventArgs e)
{
if (RE_APE_DEBUGGER_ENABLED.IsMatch(htaccessContent.Text))
var code = htaccessContent.Text;
if (RE_APE_DEBUGGER_ENABLED.IsMatch(code))
{
// already disabled, enable it!
ApeDebuggerSecureKey = RE_APE_DEBUGGER_ENABLED.Match(htaccessContent.Text).Groups[2].Value;
// alerdy enable, disable it!
code = RE_APE_DEBUGGER_ENABLED.Replace(code, "# $1");
}
ApeDebuggerUrl.Value = "";
if ( !string.IsNullOrEmpty(ApeDebuggerSecureKey) )
htaccessContent.Text = code;
SaveFolder();
StopDebugger();
}
private void GetDebuggerUrl()
{
// TODO: interactive binding selection
if ( !string.IsNullOrEmpty(DebuggerSecureKey) )
{
WebSite site = ES.Services.WebServers.GetWebSite(PanelRequest.ItemID);
WebSite site = GetWebSite();
if ( null != site)
{
if (site.Bindings.Length > 0)
{
ServerBinding serverBinding = site.Bindings[0];
ApeDebuggerUrl.Value = string.Format("{0}://{1}:{2}{3}?ape_debug={4}",
serverBinding.Protocol,
serverBinding.Host ?? serverBinding.IP,
serverBinding.Port,
folderPath.SelectedFile.Replace('\\', '/'),
ApeDebuggerSecureKey
);
DebuggerUrl = string.Format(
"{0}://{1}:{2}{3}/_ape_start_developer_session?ape_debug=secure-key-{4}_{5}",
serverBinding.Protocol,
serverBinding.Host ?? serverBinding.IP,
serverBinding.Port,
folderPath.SelectedFile.Replace('\\', '/'),
DebuggerSecureKey,
DebuggerSessionId
);
DebuggerUrlField.Value = DebuggerUrl;
}
}
}
// TODO: throw error if debugger url is empty
}
private WebSite GetWebSite()
{
WebSite webSite = ViewState["HtaccessWebSite"] as WebSite;
if (null == webSite)
{
webSite = ES.Services.WebServers.GetWebSite(PanelRequest.ItemID);
// TODO: ViewState["HtaccessWebSite"] = webSite;
}
return webSite;
}
private void GetDebuggingPageUrl()
{
if (!string.IsNullOrEmpty(DebuggerSecureKey))
{
WebSite site = GetWebSite();
if (null != site)
{
if (site.Bindings.Length > 0)
{
ServerBinding serverBinding = site.Bindings[0];
DebuggingPageUrl = string.Format(
"{0}://{1}:{2}{3}/?ape_debug=secure-key-{4}_{5}",
serverBinding.Protocol,
serverBinding.Host ?? serverBinding.IP,
serverBinding.Port,
folderPath.SelectedFile.Replace('\\', '/'),
DebuggerSecureKey,
DebuggerSessionId
);
}
}
}
// TODO: throw error if url is empty
}
private void StartDebugger()
{
ButtonDebuggerStart.Visible = false;
ButtonDebuggerStop.Visible = true;
// session id
DebuggerSessionId = new Random().Next(100000000, 999999999).ToString(CultureInfo.InvariantCulture);
// debugger url
GetDebuggerUrl();
// debugging page url
GetDebuggingPageUrl();
// show debugger iframe
DebuggerFramePanel.Visible = true;
DebuggerFrame.Attributes["src"] = DebuggerUrl;
// debugging page link
ContainerLinkDebuggingPage.Visible = true;
LinkDebuggingPage.NavigateUrl = DebuggingPageUrl;
LinkDebuggingPage.Text = DebuggingPageUrl;
}
private void StopDebugger()
{
ButtonDebuggerStart.Visible = true;
ButtonDebuggerStop.Visible = false;
DebuggerUrl = "";
DebuggingPageUrl = "";
DebuggerSessionId = "";
// hide debugger iframe
DebuggerFramePanel.Visible = false;
// hide debugging page link
ContainerLinkDebuggingPage.Visible = false;
}
protected void btnCancel_Click(object sender, EventArgs e)

View file

@ -21,6 +21,15 @@ namespace WebsitePanel.Portal {
/// </remarks>
protected global::System.Web.UI.WebControls.Label lblFolderName;
/// <summary>
/// LabelWebSiteName control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Label LabelWebSiteName;
/// <summary>
/// folderPath control.
/// </summary>
@ -40,22 +49,67 @@ namespace WebsitePanel.Portal {
protected global::System.Web.UI.WebControls.HiddenField contentPath;
/// <summary>
/// ApeDebuggerUrl control.
/// DebuggerUrlField control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.HiddenField ApeDebuggerUrl;
protected global::System.Web.UI.WebControls.HiddenField DebuggerUrlField;
/// <summary>
/// btnApeDebug control.
/// ButtonDebuggerStart control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Button btnApeDebug;
protected global::System.Web.UI.WebControls.Button ButtonDebuggerStart;
/// <summary>
/// ButtonDebuggerStop control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Button ButtonDebuggerStop;
/// <summary>
/// ContainerLinkDebuggingPage control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Label ContainerLinkDebuggingPage;
/// <summary>
/// LinkDebuggingPage control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.HyperLink LinkDebuggingPage;
/// <summary>
/// DebuggerFramePanel control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.WebControls.Panel DebuggerFramePanel;
/// <summary>
/// DebuggerFrame control.
/// </summary>
/// <remarks>
/// Auto-generated field.
/// To modify move field declaration from designer file to code-behind file.
/// </remarks>
protected global::System.Web.UI.HtmlControls.HtmlGenericControl DebuggerFrame;
/// <summary>
/// htaccessContent control.

View file

@ -4929,7 +4929,9 @@
<SubType>Designer</SubType>
</Content>
<Content Include="ScheduleTaskControls\App_LocalResources\NotifyOverusedDatabases.ascx.resx" />
<Content Include="App_LocalResources\WebSitesEditHeliconApeFolder.ascx.resx" />
<Content Include="App_LocalResources\WebSitesEditHeliconApeFolder.ascx.resx">
<SubType>Designer</SubType>
</Content>
<Content Include="App_LocalResources\WebSitesEditHeliconApeFolderAuth.ascx.resx" />
<Content Include="App_LocalResources\WebSitesEditHeliconApeGroup.ascx.resx" />
<Content Include="App_LocalResources\WebSitesEditHeliconApeUser.ascx.resx" />