Parsing cs50 pset6服务器解析功能-未通过cs50服务器1检查

Parsing cs50 pset6服务器解析功能-未通过cs50服务器1检查,parsing,server,cs50,Parsing,Server,Cs50,您能否就cs50 check server1中显示的错误给出一些建议,并就如何解决这些错误提供一些指导: 我的解析函数如下所示: bool parse(const char* line, char* abs_path, char* query) { // create copy of line char linecopy[strlen(line)+1]; strcpy(linecopy, line); linecopy[strlen(line)] = '\0';

您能否就cs50 check server1中显示的错误给出一些建议,并就如何解决这些错误提供一些指导:

我的解析函数如下所示:

bool parse(const char* line, char* abs_path, char* query)

{
   // create copy of line
   char linecopy[strlen(line)+1];
   strcpy(linecopy, line);
   linecopy[strlen(line)] = '\0';



 int spaces = 0;
   for (int i = 0, lenght = strlen(line); i < lenght; i++)
    {
    if (line[i] == ' ')
    spaces++;

    if (spaces > 2)
    {
        error(400);
        return false;
    }
    }
   char* methodcopy;
   char* targetcopy;
   char* httpcopy;

    // extract method, request-target, and http version to tokens
    methodcopy = strtok(linecopy, " ");
    targetcopy = strtok(NULL, " ");
    httpcopy = strtok(NULL, "\r\n");

    //copy tokens into method, target and http

    char method[strlen(methodcopy) + 1];
    strcpy (method, methodcopy);
    char target[strlen(targetcopy) + 1];
    strcpy(target, targetcopy);
    char http[strlen(httpcopy) + 1];
    strcpy(http, httpcopy);

    // add null terminators

    method[strlen(method)] = '\0';
    target[strlen(target)] = '\0';
    http[strlen(http)] = '\0';

    // ensure method is GET

    if(strncmp(method, "GET", 4)!= 0)
    {
        error(405);
    }
   // ensure request-target begins with "/"
   if(strchr(target, '/') == NULL)
   {
       error(501);

   }
    // ensure request-target does not contain '"'
    if (strchr(target, '"') != NULL)
        {
            error(400);
        }
   // ensure HTTP version is 1.1
   if(strcmp(http, "HTTP/1.1") != 0)
   {
       error(505);

   }

   // extract query from request-target
   char* abs_pathcopy;
   char* querycopy;
   abs_pathcopy = strtok(target, "?");
   querycopy = strtok(NULL, "\0");

   //if query isn't null, copy to query
   if (querycopy != NULL)
   {
       strcpy(abs_path, abs_pathcopy);
       strcpy(query, querycopy);

       abs_path[strlen(abs_pathcopy)] = '\0';
       query[strlen(querycopy)] = '\0';
   }
   //if query is null, set query to null
        else 
        {
            strcpy(abs_path, abs_pathcopy);
            abs_path[strlen(abs_pathcopy)] = '\0';
            query[0] = '\0';
        }
    // ensure absolute path does not contain "?"
    if(strchr(abs_path, '?') != NULL)
    {
        error(400);

    }
    // ensure query does not contain '"'

    if(strchr(abs_path, '"') != NULL)
    {
        error(400);

    }
    return true;
}
bool解析(常量字符*行,字符*abs\u路径,字符*查询)
{
//创建行的副本
字符行拷贝[strlen(行)+1];
strcpy(行拷贝,行);
行复制[strlen(行)]='\0';
int空间=0;
for(int i=0,lenght=strlen(行);i2)
{
误差(400);
返回false;
}
}
字符*方法副本;
字符*目标拷贝;
字符*httpcopy;
//将方法、请求目标和http版本提取到令牌
methodcopy=strtok(linecopy,“”);
targetcopy=strtok(空,“”);
httpcopy=strtok(空,“\r\n”);
//将令牌复制到方法、目标和http中
char方法[strlen(methodcopy)+1];
strcpy(方法,方法副本);
字符目标[strlen(targetcopy)+1];
strcpy(target,targetcopy);
字符http[strlen(httpcopy)+1];
strcpy(http,httpcopy);
//添加空终止符
方法[strlen(方法)]='\0';
目标[strlen(target)]='\0';
http[strlen(http)]='\0';
//确保方法是正确的
if(strncmp(方法“GET”,4)!=0)
{
错误(405);
}
//确保请求目标以“/”开头
if(strhr(目标“/”)==NULL)
{
错误(501);
}
//确保请求目标不包含“”
if(strhr(目标“,”)!=NULL)
{
误差(400);
}
//确保HTTP版本为1.1
如果(strcmp(http,“http/1.1”)!=0)
{
错误(505);
}
//从请求目标提取查询
char*abs_路径副本;
字符*查询副本;
abs_pathcopy=strtok(目标为“?”);
querycopy=strtok(空,“\0”);
//如果查询不为null,请复制到查询
if(querycopy!=NULL)
{
strcpy(abs\u路径,abs\u路径副本);
strcpy(查询、查询副本);
abs_路径[strlen(abs_路径副本)]='\0';
查询[strlen(querycopy)]='\0';
}
//如果查询为空,则将查询设置为空
其他的
{
strcpy(abs\u路径,abs\u路径副本);
abs_路径[strlen(abs_路径副本)]='\0';
查询[0]='\0';
}
//确保绝对路径不包含“?”
if(strchr(abs_路径,“?”)!=NULL)
{
误差(400);
}
//确保查询不包含“”
if(strchr(abs_路径,“)!=NULL)
{
误差(400);
}
返回true;
}
当我对服务器1执行cs50检查时,显示了以下错误:

:(abc/hello.php的请求目标返回错误代码501 \预期输出,但不是“未找到HTTP/1.1 404\r\n内容类型:…”

:(请求cat.exe返回错误代码501 \预期输出,不是0的退出代码

:(GET后面的两个空格返回错误代码 \预期输出,不是0的退出代码

根据我的理解,请求行不符合以下定义:

方法SP请求目标SP HTTP版本CRLF

但不知道如何定义它

欢迎提供任何提示和建议!我不需要解决方案,只需要一些提示;)


感谢所有花时间阅读这个长问题的人!

您的算法首先假设输入行是一个格式良好的请求,然后将其分成几部分,然后检查分割的部分。您现在如何定义“”(SP)在正确的位置和正确的数量?如果我从不使用SP或在任何地方都使用双SP怎么办

简言之,我认为您不应该将strtok()与一个您不知道其形式正确性的字符串一起使用。逐个字符解析输入或使用类似于检测delimeter发生的函数

使用strchr()时编辑:

我为strchr()链接的文档说“返回一个指向C字符串str.中第一次出现的字符的指针”。因此,如果一个字符串像“1*2*3*4\0”,其中“*”是delimeter

char* firstStar =strchr(myString, '*') 
将返回指向第一颗星的指针

char* secondStar =strchr(firstStar + 1, '*') 
将返回第二颗星,因为您说过从第一颗星开始搜索。 如果找不到指定的字符,此函数将返回null。 (参见给定链接中的示例)


现在我可以通过使用函数来检索第二个参数“2”,因为我知道它从哪里开始(在firstStar+1)以及它的长度(secondStar-firstStar)。请注意,在使用strncpy()之后您应该手动将空终止符“\0”放在复制字符串的末尾。

@t.m.-谢谢!我按照您的建议编辑了开头的代码,并检查了请求行中的空格数,这解决了其中一个错误(:(GET后两个空格返回错误代码\预期输出,而不是退出代码0)但是我仍然有另外两个错误,而且我一直在试图找到一个解决方案,如何根据定义确定请求行的正确性:方法SP target SP http\r\n…..此外,我不理解所指示错误的含义::(abc/hello.php的请求目标返回错误代码501\预期输出,但不是“找不到HTTP/1.1 404\r\n内容类型:…”:(请求cat.exe返回错误代码501 \预期输出,而不是您提供的解决方案的退出代码0-使用strchr检测delimeter-不确定如何实现。一般来说,如果我了解错误的含义,我认为我可以解决问题。)n、 …这些错误是用奇怪的语法写的:)。我估计:(abc/hello.php的请求目标返回错误代码501 \预期输出,但不是“HTTP/1.1 404未找到\r\n内容类型:…”意味着“abc/hello.php的请求目标”的输出应该是错误代码501,但您的输出是“HTTP/1.1 404未找到\r\n内容类型:。。。“我将进行编辑,更详细地解释strhr()的用法。用于调试您请求cat.exe和其他文件时发生的情况。