0

I implemented the parse function as below. The main idea is to divide the line into method, request, http version, check if they are consistent with rules. And then parse the request into abs_path and query. I used check50 and receive 2 failure info: [![enter image description here][1]][1]

For the 404 error, I understand that the abs_path and query variables are not really passed to the main function. Thus, in the main function that error check is skipped. But I don't know how to fix it. If using double pointer, should I change also the main function when calling the procedure?

bool parse(const char* line, char* abs_path, char* query)
{
    char* tmp = malloc(sizeof(char) * (strlen(line) + 1));
    strcpy(tmp, line);

    //get the method, request, http version
    char* method = strtok(tmp, " ");
    char* request_target = strtok(NULL, " ");
    char* http_ver = strtok(NULL, "\r\n");

    //check if method is "GET"
    if (strcmp(method, "GET") != 0)
    {
        error(405);
        return false;
    }

    // check if request-target begins with /
    if (request_target[0] != '/')
    {
        error(501);
        return false;
    }

    // check if request-target contains "
    if (strchr(request_target, '\"') != NULL)
    {
        error(400);
        return false;
    }

    //check if http version is HTTP/1.1
    if (strcmp(http_ver, "HTTP/1.1") != 0)
    {
        error(505);
        return false;
    }

    //parse path and query
    char* haystack = request_target;
    char* needle = strchr(haystack, '?');

    // if a query doesn't exist
    if (needle == NULL)
    {
        strcpy(abs_path, haystack);
        abs_path[strlen(haystack)] = '\0';
        query[0] = '\0';
    }
    //if the request ends with ?
    else if (strlen(needle) == 1)
    {
        strncpy(abs_path, haystack, needle - haystack);
        abs_path[strlen(haystack) - strlen(needle)] = '\0';
        query[0] = '\0';
    }
    //if a query exists, parse path and query
    else 
    {
        strncpy(abs_path, haystack, needle - haystack);
        abs_path[strlen(haystack) - strlen(needle)] = '\0';
        strcpy(query, needle + 1);
    }

    error(501);
    return false;
}

EDIT: rolled the edits back to what the answer was about, otherwise this question won't benefit future users.

2

You're already doing most things right.

Reading your code, I believe you're at a level to solve this for yourself (you just need the right tools!).

For this reason, instead of answering you, I'll show you your program in a visual debugger so you can see for yourself what you're doing wrong and try to fix it accordingly.

Here is your code (wait some seconds for it to load and the navigate clicking forward or back. You can edit it as well and run again).

If this is enough to solve your problem, please click the check mark to accept this answer.

If it isn't, you can comment below and tell what more you need.

EDIT to reflect your edits:
1 - You've changed abs_path and query from pointers (char*) to pointers to pointers (char**). You shouldn't do that.
2 - You need to return true at the end of the function. If you only return false, it will be as if the function is always failing.
3 - That error(501) before the return value shouldn't be there also, or else it will be triggered every time the function reaches it's end, even when no errors were actually present.

| improve this answer | |
  • I understand that when I first use "strtok()" function, I'm parsing a string, or an array of chars, so to speak. I want to do the same thing with request-target, but all of them(method, request_target, http_ver) are just pointers to a string. I'm really confused with strings, arrays, pointers, addresses right now. – Xuying Shao Dec 6 '16 at 1:44
  • Basically what's left for you is to correct this typo here: char* http_ver = strtok(NULL, "/r/n"); (should be \r\n) and then null terminate abs_path (you're not doing so). – Yuri Laguardia Dec 6 '16 at 2:53
  • typo!!! I didn't even pay attention to it. Now the "cat.exe error code 501" problem is solved. For the 404 problem, I think the key is to pass the abs_path and query to main function by reference instead of by value. Still working on it. And the visualization is really helpful for debugging. Thank you. – Xuying Shao Dec 6 '16 at 3:34
  • 1
    yes, I finally got it. I changed the distribution code, particularly thees two line "error(501); return false" into "return true;". Then I got the error about two spaces after GET. So I add some lines to check if there are more than 2 spaces in line. Now it works. Thank you. – Xuying Shao Dec 6 '16 at 22:41
  • 1
    OMG! I've been using Python Tutor forever and never noticed that it had an 'experimental' C feature! Thanks for posting this answer @YuriLaguardia. It helped with both PSET 6 and so much more! – Ryan Jan 4 '17 at 1:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .