2016-11-23 35 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內容類型:...「 –