0

I have made done parse and lookup, and the result for check50 after completing these two functions gives 2 fails in getting cat.exe and a non-existant file. The error for both is

\ expected output, but not "HTTP/1.1 301 Moved Permanently\r\nLocat..."

After many trials, I have searched online to find some posts here that talk about abs_path not being terminated properly when using strncpy(). I think I have terminated it as needed, but the two red errors are still there unchanged. I hope for any hint.

lookup

const char* lookup(const char* path) {
   char * ext = strchr(path,'.');
            if (strcasestr(ext,".css") != NULL) 
                return "txt/css";
            else if(strcasestr(ext,".html") != NULL) 
                return "txt/html";
            else if(strcasestr(ext, ".gif") != NULL)
                return "image/gif";
            else if(strcasestr(ext, ".ico") != NULL)
                return "image/x-ico";
            else if(strcasestr(ext, ".jpg") != NULL)
                return "image/jpeg";
            else if(strcasestr(ext,".js") != NULL)
                return "text/javascript";
            else if(strcasestr(ext,".php") != NULL)
                return "text/x-php";
            else if(strcasestr(ext, ".png") != NULL)
                return "image/png";
            else
                return NULL;
    }

parse

bool parse(const char* line, char* abs_path, char* query)
{
    // TODO
    int i = 0, spaceReg = 0, indxSecSpc = 0, indxFirstSpc;
    int j = 0;
    size_t sizeOfReq = strlen(line);
    int sizeOfReqInt = sizeOfReq; 
    bool flagQ = true;
    char * method;
    char * request_target = calloc(sizeOfReq,sizeof(char));
    method = "GET ";
    char * request_targetL = calloc(sizeOfReq,sizeof(char));
    /*Start of Operation*/
        if(strstr(line,method) == NULL || line[0] !='G'){
            error(405);
            return false;
        }
            for(i = 0; i <sizeOfReq; i++) {
                    if (line[i] == ' ') {
                        spaceReg++;
                        if(spaceReg == 1) 
                            indxFirstSpc = i;
                        else if(spaceReg == 2)
                            indxSecSpc = i;
                    }
                }
        if (spaceReg > 2) {
            error(400);
            return false;
        }
        else if (spaceReg < 2) {
            return false;
        }
        else if(line[sizeOfReq-1] != '\n' && line[sizeOfReq-2] != '\r') {
            return false;
        }
        else if(line[indxFirstSpc+1] != '/') {
            error(501);
            return false;
        }
        else {
            int indxReqTar = indxFirstSpc+1;
            size_t reqTarSize = indxSecSpc-indxReqTar;
            request_targetL = strchr(line,'/');
            strncpy(request_target,request_targetL,reqTarSize);
            j = 0;
            flagQ = true;
            if(strchr(request_target,'"') != NULL) {
                error(400);
                return false;
            }
            /*Store query*/
            bool flagV = true;
            j =0;
            int indxOfQuery = 0;
            if(strstr(request_target,"q=") == NULL) {
                query[0]='\0';
            }
            else {
                 while(flagV){
                    if(request_target[j] == '=') {
                        indxOfQuery = j-1;
                        flagV = false;
                    }
                    j++;
                }   
                    size_t absPathSize = indxOfQuery - indxFirstSpc-1;
                    strncpy(abs_path,request_target,absPathSize);
                    abs_path[absPathSize+1] = '\0';
                    free(request_target);
                    query = strstr(request_target,"q=");
                    query[LimitRequestLine + 1] = '\0';
            }
            j=0;
            flagV = true;
            int indxHTTPver = indxSecSpc+1;
            char * httpVer = calloc(sizeOfReq,sizeof(char));
            while(flagV) {
                httpVer[j] = line[indxHTTPver+j];
                j++;
                if (indxHTTPver+j == sizeOfReqInt)
                    flagV=false;
            }
            if(strcasestr(httpVer,"HTTP/1.1") == NULL ) {
                error(505);
                free(httpVer);
                return false;
            }
      }
    free(request_target);
    return true;
}

2 Answers 2

1

If memory serves, The 301 error comes from a blank abs_path.

Problems start here:

int indxOfQuery = 0;
if(strstr(request_target,"q=") == NULL) {

A query is indicated by '?', not by 'q='. From the specification:

Per 5.3 of the same RFC, request-target, meanwhile, can take several forms, the only one of which your server needs to support is

absolute-path [ "?" query ]

whereby absolute-path (which will not contain ?) must start with / and might optionally be followed by a ? followed by a query, which may not contain ".

So that if will always evaluate to true. Therefore the else is not executed. What will happen next? size_t absPathSize = indxOfQuery - indxFirstSpc-1;. indxOfQuery is always 0, so absPathSize is less than 0, so the strncpy won't do anything (not anything good), so abs_path is not populated. Remember, after the if is fixed to look for the correct thing, the else will not be executed if there is not a query, so there will still be a problem with absPathSize calculation.

pset6 server is a great exercise to get the full benefit of debug50 and/or gdb. It usually takes a bit of practice, patience and perseverance but either will ultimately help you troubleshoot your code.

1
  • Thanks, the problem was in the calculation of 'absPathSize' in various cases as you said. Nov 23, 2016 at 23:24
1

Let me just point out to you a critical mistake and see if you can fix the rest by yourself with just this.

  • All HTML elements can have attributes
  • Attributes provide additional information about an element
  • Attributes are always specified in the start tag
  • Attributes usually come in name/value pairs like: name="value"

This line:

if(strstr(request_target,"q=") == NULL)

Assumes that the name of the attribute for the query string will always be q, but that's not true.

The attribute can have any name the web developer decides to put inside his html tag. Take this imaginary GET request line for example:

"GET /hello.php?name=Alice HTTP/1.1\r\n"

There the name of the attribute for query is name and the value is Alice, so your code won't work, because you're always looking for q as the name of the attribute.

You must log in to answer this question.

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