C#没有任何理由没有打破循环

时间:2011-04-05 13:22:44

标签: c# vhosts

我正在编写一些解析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]);
            }
        }
    }

hostsvHost[] 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内再次调用vhost,即使我清空了addRule,所以里面没有代码这仍然无效。

这是我能够显示问题的唯一方法,因为错误似乎与编译的最终结果一致,所以没有更小的复制方式

我找到的唯一方法是评论或从我的代码中移除hosts[c].addRule(param[0], param[1]);然后它可以工作,但如上所述,当我清空它时,它不起作用,理论上不正确

虽然代码执行但它没有发生错误,它只运行循环一次,

不存在任何错误,这不包括任何异常的死亡,也不会造成任何冻结/崩溃

更新 更新的读者

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“

3 个答案:

答案 0 :(得分:2)

只是为此提供一个实际答案:

我的初步猜测 - 这只是一个猜测,因为我们没有我们需要的所有信息 - 是在循环中的某处抛出异常。

我能看到的最有可能的候选人是该行:

hosts[c].addRule(param[0], param[1]);

vhost类中的addRule方法做了一些非常时髦的东西,但同样,我们没有所有的信息,所以我不能肯定地说。

我们需要什么

我们至少需要知道发生了什么。是抛出异常吗?它走了什么路线?它会默默地死吗?你介入过代码了吗?

请帮助我们帮助你......

<强>更新
所以,问题在于:

string[] param = line.Trim().Split(' ');                
hosts[c].addRule(param[0], param[1]);            

OR:

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;
    }

OR:

vhostRules的构造函数中,如行所示:

rules[counter] = new vhostRules();

现在,您在rules[]中使用键值对的关键是什么?

您可以尝试
更改行:

string[] param = line.Trim().Split(' ');

为:

string[] param = line.Trim().Split(new char[] {' '}, 2);

这样您就可以将common保留在某些行的末尾......这可能不会导致您的主要问题,但可能会出现 问题至少

更新2
在上面一行(string[] param = line.Trim().Split(new char[] {' '}, 2);后面设置一个断点,看看实际设置了什么参数。添加一个监视,看完全 param [0]和param [1]是什么。我有感觉他们没事,而且实际上是在 的addRule方法中抛出了异常......

再次,在addRule方法中的代码周围添加错误处理,并查看输出内容。查看堆栈跟踪,检查行号,并准确地向我们显示那里发生的事情。

答案 1 :(得分:2)

不是解决问题的方法,但至少要进行一些清理:更改此行:

public vhostRules[] rules = new vhostRules[1];

进入

private List<vhostRules> rules = new List<vhostRules>();

那么每次需要添加项目时都不需要重新复制该数组,只需要.Add()

然后您可以更改

public vhostRules[] getRules()
{
    return rules;
}

进入

using System.Linq;
public vhostRules[] getRules()
{
    return rules.ToArray();
}

答案 2 :(得分:1)

我想我找到了它。您可以为每个虚拟主机定义中的每一行执行此代码:

/* 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]);

这假定每行包含至少2个以空格分隔的值。对于所有人来说都是如此除了之外的最后一个:</VirtualHost>

我希望你得到一个ArrayIndexOutOfBoundsException(或者在.NET中调用的任何东西),但似乎有些东西可以吞下去。