cs50 pset6服务器解析函数 - 不通过cs50服务器1检查

时间:2016-11-23 13:53:12

标签: 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';



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

当我执行cs50检查服务器1时,我指出了以下错误:

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

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

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

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

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

但不确定如何定义....

欢迎任何提示和建议!我不想要解决方案,只是一些迹象;)

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

1 个答案:

答案 0 :(得分:0)

你的算法首先假设输入行是一个格式良好的请求,而不是将它分成片段,而不是检查分割的部分。你现在如何将“”(SP)确切地放在正确的位置和正确的数字?如果我从不使用SP或在任何地方使用双SP怎么办?

简而言之,我认为你不应该将strtok()与一个你不了解其形式正确性的字符串一起使用。通过char解析输入char或使用像strchr()这样的函数来自己检测deimeter的出现。

使用strchr()进行编辑:

我为strchr()链接的文档strchr()说“返回指向C字符串str中第一个字符出现的指针”。所以,如果有一个像“一个*两个*三个*四个\ 0”的字符串,其中'*'是分隔符;

char* firstStar =strchr(myString, '*') 

将返回指向第一个星的指针

char* secondStar =strchr(firstStar + 1, '*') 

将返回第二颗星,因为你说从第一颗星开始接收。  如果找不到您指定的字符,则此函数返回null。  (参见给定链接的示例)

现在我可以使用strncpy()函数检索第二个参数“2”,因为我知道它在哪里开始(在第一星+1)和它有多长(第二星 - 第一星)注意你使用strncpy()之后你应该在复制字符串的末尾手动放置空终结符'\ 0'。