0

I have been working on this pset for a long time now. I feel like the real challenge in this pset is debugging and I can't seem to find out where my problem is. I have an idea that it might be in the index or load function, but I am not sure. I have been testing my functions in another file, learn.c, and it looks like they should be working. Any help would be greatly appreciated.

When running the server.c file, I get:

Using /home/ubuntu/workspace/pset6/public for server's root

Listening on port 8080

GET / HTTP/1.1

HTTP/1.1 403 Forbidden

Segmentation fault

This is what i get when i run check50 2015.fall.pset6.server2 server.c:

:) server.c exists

:) server compiles

:( Requesting cat.jpg returns 200, image/jpeg, and correct image

:( Requesting cat.html returns 200, text/html, and correct file

:( Requesting cat2.HTML returns 200, text/html, and correct file

:( Requesting cat3.HtMl returns 200, text/html, and correct file

:( Requesting cat.gif returns 200, image/gif, and correct file

:( Requesting favicon.ico returns 200, image/x-icon, and correct file

:( Requesting test.css returns 200, text/css, and correct file

:( Requesting test.js returns 200, text/javascript, and correct file

:( Requesting hello.php returns 200, text/html, and correct output

\ expected output, not an exit code of 0

:( Requesting hello.php? returns 200, text/html, and correct output

\ expected output, not an exit code of 0

:( Requesting hello.php?name=Alice returns 200, text/html, and correct output

\ expected output, not an exit code of 0

:) Requesting /test redirects to /test/

:( Requesting /test/ outputs /test/index.html

:( Requesting directory containing index.php outputs index.php

\ expected output, not standard error of "======= Backtrace: =========\n======= M..."

:( Requesting two files in a row (cat.html then cat.jpg) succeeds

lookup:

const char* lookup(const char* path)
{
    const char c = '.';

    char* ex = strrchr(path, c);
    char extension[sizeof(ex)];

    for (int i = 0; i < strlen(ex); i++){
        extension[i] = tolower(ex[i]);
    }

    if (strcmp(extension, ".css") == 0){
        return "text/css";
    }
    else if (strcmp(extension, ".html") == 0){
        return "text/html";
    }
    else if (strcmp(extension, ".gif") == 0){
        return "image/gif";
    }
    else if (strcmp(extension, ".ico") == 0){
        return "image/x-icon";
    }
    else if (strcmp(extension, ".jpg") == 0){
        return "image/jpeg";
    }
    else if (strcmp(extension, ".js") == 0){
        return "text/javascript";
    }
    else if (strcmp(extension, ".php") == 0){
        return "text/x-php";
    }
    else if (strcmp(extension, ".png") == 0){
        return "image/png";
    }

    return NULL;
}

parse: (Sorry for the bad variable names, I know this is bad coding but i think the logic is working)

bool parse(const char* line, char* abs_path, char* query)
{
    int spaces = 0;
    int temp1 = -1;
    int temp2 = -1;
    int staticI;

    bool q = false;

    char requestTarget[LimitRequestLine + 1];
    char HTTPVersion[LimitRequestLine + 1];
    char method[LimitRequestLine + 1];
    char queryText[LimitRequestLine + 1];

    memset(requestTarget, '\0', LimitRequestLine + 1);
    memset(HTTPVersion, '\0', LimitRequestLine + 1);
    memset(method, '\0', LimitRequestLine + 1);
    memset(queryText, '\0', LimitRequestLine + 1);

    for (int i = 0; i < strlen(line); i++){
        if (line[i] == 32){
            spaces++;
        }
        else{
            if (spaces == 0){
                method[i] = line[i];
            }
            else if (spaces == 1){
                if (temp1 == -1){
                    temp1 = i;
                }
                requestTarget[i-temp1] = line[i];

            }
            else if (spaces == 2){
                if (temp2 == -1){
                    temp2 = i;
                }
                HTTPVersion[i-temp2] = line[i];
            }
        }
    }

    for (int i = 0; i < 20; i++){
        // 32 is a space in ascii
        if (method[i] == 32 || requestTarget[i] == 32 || HTTPVersion[i] == 32){
            error(400);
            return false;
        }
    }

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

    // 47 is / in ascii
    if (requestTarget[0] != 47){
        error(501);
        return false;
    }

    for (int i = 0; i < strlen(requestTarget); i++){
        // 34 is " in ascii
        if (requestTarget[i] == 34){
            error(400);
            return false;
        }
        // 63 is ? in ascii
        if (requestTarget[i] == 63){
            q = true;
            staticI = i+1;
        }else{
            if (q){
                queryText[i - staticI] = requestTarget[i];
            }else{
                abs_path[i] = requestTarget[i];
            }
        }
    }

    if (strcmp(HTTPVersion, "HTTP/1.1\r\n") != 0){
        error(505);
        return false;
    }

    strcpy(query, queryText);
    return true;
}

load:

bool load(FILE* file, BYTE** content, size_t* length)
{
    if (file == NULL){
        return false;
    }

    char* buffer = malloc(sizeof(BYTE));

    for (char c = fgetc(file); c != EOF; c = fgetc(file)){
        buffer = realloc(*content, sizeof(*content) + sizeof(BYTE));
        *length = *length + 1;
    }

    *content = &buffer[0];
    return true;
}

indexes:

char* indexes(const char* path)
{
    char* php  = "/index.php";
    char* html = "/index.html";

    char* path2 = malloc(sizeof(php) + sizeof(path) + 1);
    strcpy(path2, path);
    strcat(path2, php);

    if (access(path2, R_OK) != -1){
        return path2;
    }

    strcpy(path2, path);
    strcat(path2, html);

    if (access(path2, R_OK) != -1){
        return path2;
    }

    return NULL
}

1 Answer 1

1

Yes, debugging server is challenging. It takes patience, practice and perseverance. You will find intro material for debug50 here, and some tips on gdb here. It is really worth the investment of time. I have found it easier to debug with curl requests instead of browser requests. The main thing to remember is: if server is not doing anything, it is probably waiting for a request. If the curl (or browser) request is not doing anything, it is probably at a break point in server.

The overriding problem in all the functions is sizeof. In indexes: sizeof(php) + sizeof(path) php is a pointer. sizeof a pointer is 8. You probably meant length of (think strlen).

Same problem here char extension[sizeof(ex)]; in lookup. Remember, this char* ex = strrchr(path, c); will return a pointer into path starting at c. It seems like a lot of extra work to build extension. Review the man page for strcasecmp to see how you could make this function more efficient.

In load this sizeof(*content) is a problem. Plus, buffer is never populated.

After you get that stuff sorted, you'll probably need to double down with gdb. This \ expected output, not an exit code of 0 from check50 is a segmentation fault. It is difficult to say whether it is a result of the allocation problems already mentioned or some other problem(s) in parse.

You must log in to answer this question.

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