Apache 構成ファイルを解析するコードを書いています。
解析中のファイル:
NameVirtualHost *:80
#
# VirtualHost example:
# Almost any Apache directive may go into a VirtualHost container.
# The first VirtualHost section is used for all requests that do not
# match a ServerName or ServerAlias in any <VirtualHost> block.
#
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host.example.com
DocumentRoot "c:/Apache2/docs/dummy-host.example.com"
ServerName dummy-host.example.com
ServerAlias www.dummy-host.example.com
ErrorLog "logs/dummy-host.example.com-error.log"
CustomLog "logs/dummy-host.example.com-access.log" common
</VirtualHost>
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host2.example.com
DocumentRoot "c:/Apache2/docs/dummy-host2.example.com"
ServerName dummy-host2.example.com
ErrorLog "logs/dummy-host2.example.com-error.log"
CustomLog "logs/dummy-host2.example.com-access.log" common
</VirtualHost>
これはパーサー メソッドです。 filePath は上記のファイルへのパスです。
public void readFile(string filePath)
{
/* read the file path provided */
StreamReader reader = new StreamReader(filePath);
string content = reader.ReadToEnd();
/* remove the comments from the file */
string[] lines = content.Split('\n');
string newContent = "";
foreach(string line in lines){
char[] chars = line.ToCharArray();
if(chars[0] != '#'){
newContent += line+"\n";
}
}
/* search for Virtual hosts and save them */
string regEx = "<VirtualHost [^>]*>[^<]*</VirtualHost>";
MatchCollection coll = Regex.Matches(newContent, regEx, RegexOptions.IgnoreCase);
string[] vhosts = new string[coll.Count];
int counter = 0;
/* go though them and save them into a string array */
foreach (Match match in coll)
{
vhosts[counter] = (match.Value);
counter++;
}
/* set the number of vhosts */
hosts = new vhost[vhosts.Count()];
/* go though the string array */
for (int c = 0; c < vhosts.Count(); c++ )
{
MessageBox.Show("hi");
/* set the host string to current vhost string */
string host = vhosts[c];
/* get the lines from the vhost */
string[] lines2 = host.Split('\n');
/* create the new save object in the array of vhosts */
hosts[c] = new vhost();
/* tell the console what were proccessing */
Console.WriteLine((c+1).ToString() + " of " + vhosts.Count().ToString());
/* for each line add the rule to the correct vHost via the counter for looping though the vhosts */
for (int i = 0; i < lines2.Count(); i++)
{
/* set the string line to the line were currently on */
string line = lines2[i];
/* get rid of whitespace and split on the space (' ')*/
string[] param = line.Trim().Split(' ');
/* provde the current vHost number and the key and value in the config file */
hosts[c].addRule(param[0], param[1]);
}
}
}
hosts
vHostはvHost[]
以下の通りです
class vhost
{
public vhostRules[] rules = new vhostRules[1];
public string getRuleValue(string key)
{
vhostRules[] currentRules = rules;
rules = new vhostRules[currentRules.Count()];
for (int i = 0; i < currentRules.Count(); i++)
{
vhostRules Rule = currentRules[i];
if (key == Rule.key)
return Rule.value;
}
return "";
}
public vhostRules getRule(string key)
{
vhostRules[] currentRules = rules;
rules = new vhostRules[currentRules.Count()];
for (int i = 0; i < currentRules.Count(); i++)
{
vhostRules Rule = currentRules[i];
if (key == Rule.key)
return Rule;
}
return new vhostRules();
}
public vhostRules[] getRules()
{
return rules;
}
public void addRule(string key, string rule)
{
vhostRules[] currentRules = rules;
rules = new vhostRules[currentRules.Count()];
int counter = 0;
for (int i = 0; i < currentRules.Count(); i++)
{
vhostRules Rule = currentRules[i];
rules[i] = Rule;
counter++;
}
rules[counter] = new vhostRules();
rules[counter].key = key;
rules[counter].value = rule;
}
public void removeRule(string key)
{
vhostRules[] currentRules = rules;
rules = new vhostRules[currentRules.Count()];
for (int i = 0; i < currentRules.Count(); i++)
{
vhostRules Rule = currentRules[i];
if (key != Rule.key)
rules[i] = Rule;
}
}
public void changeRule(string key, string value)
{
vhostRules[] currentRules = rules;
rules = new vhostRules[currentRules.Count()];
for (int i = 0; i < currentRules.Count(); i++)
{
vhostRules Rule = currentRules[i];
if (key != Rule.key)
{
rules[i] = Rule;
rules[i].value = value;
}
}
}
}
vhostRules オブジェクト
class vhostRules { public string key; public string value; }
基本的にキーとvhostRules
値を保存するクラスです
問題はhosts[c].addRule(param[0], param[1]);
上記の読み取りファイルにあります。addRule を空にしても、addRule
クラス内で再び上記のように呼び出していることがわかります。vhost
これは、エラーがコンパイルされた最終結果にあるように見えるため、複製するより小さな方法がないという問題を示すことができる唯一の方法です
私が見つけた唯一の方法は、コメントを削除するかhosts[c].addRule(param[0], param[1]);
、コードから削除すると機能しますが、上記のように空にすると機能せず、理論的には正しくありません
エラーは発生せず、ループは 1 回だけ実行されます。
エラーは発生しません これにはサイレントデスは含まれません 例外もフリーズ/クラッシュもありません
update 更新されたリーダー
try
{
hosts[c].addRule(param[0], param[1]);
}catch (Exception e) { Console.WriteLine(e.Message); }
出力を提供します
1 of 2
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
2 of 2
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
Index was outside the bounds of the array
ブレイクポイント情報
param = {string[2]}
[0] = "ServerAdmin"
[1] = "webmaste
r@dummy-host.example.com"