2016-11-23 70 views
-1

你能给上究竟是CS50检查server1的指示的错误的一些建议和一些指导如何解决这些问题:CS50 pset6服务器解析功能 - 不通过CS50服务器1个检查

我的解析函数看起来像这样:

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返回错误代码501 \预期的输出,但不“HTTP/1.1 404未找到\ r \ n内容类型: ......”

:(请求cat.exe返回错误代码501 \预期产出,而不是获取后返回错误代码0

:(两个空间的退出代码\预期产出,而不是出口0

按我的理解代码,请求行不按定义:

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

,但不知道怎么定义的? 。

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

感谢大家花时间阅读这个长问题!

回答

0

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

总之,我不认为你应该使用strtok()和一个你不知道它的形式是否正确的字符串。通过char解析输入字符或使用像strchr()这样的函数来自己检测分隔符的发生。在和strchr使用的

编辑():

我联系了,和strchr文件strchr()()说“返回一个指针,在C字符串str字符中第一次出现。”所以,如果一个字符串像“one * two * three * four \ 0”,其中'*'是分隔符;

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

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

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

因为你说开始从firstStar seaching将返回第二颗星。 如果找不到指定的字符,则此函数返回null。 (见在给定链路的例子)

现在我可以检索第二paramater“两节”通过使用strncpy()功能,因为我知道它在哪里开始(在firstStar +1),它是多长时间(secondStar - firstStar)注意在使用strncpy()之后,应该在复制字符串的末尾手动添加空终止符'\ 0'。

+0

@ t.m. - 谢谢!我遵循你的建议,并在开始时编辑我的代码,并检查请求行中的空格数量,并解决了其中一个错误(:(GET后两个空格返回错误代码\预期输出,而不是退出代码0)但我仍然有其他两个错误,而且我坚持试图找到一个解决方案如何根据定义确定请求行的正确性:方法SP目标SP http \ r \ n ..... – SnezhinaT

+0

也,我不理解所指出的错误的含义::(请求目标的abc/hello.php返回错误代码501 \期望的输出,但不是“HTTP/1.1 404未找到\ r \ n内容类型:...” : (请求cat.exe返回错误代码501 \期望的输出,而不是您提供的解决方案的退出代码 - 使用strchr检测分隔符 - 不知道如何实现它。一般来说,如果我理解了什么,错误的意思是...... – SnezhinaT

+0

这些错误是写在一个奇怪的语法:)。我估计:(请求目标的abc/hello.php返回错误代码501 \期望的输出,但不是“HTTP/1.1 404未找到\ r \ n内容类型:...”意味着输出为“请求目标的abc /hello.php“应该是错误代码501,但输出是”HTTP/1.1 404 Not Found \ r \ n内容类型:...“ –