Making a simple HTTP webserver, using errno to reply with "403 Forbidden" and then redirect to a 403 page?

StackOverflow https://stackoverflow.com/questions/19161321

Question

I'm making a simple HTTP webserver, and this is the relevant portion of the code:

179         stat(path, &rd_perm); /* path contains the full path to the original file request */
180         if(errno == EACCES){ /* We don't have permissions to view the file... */
181                 printf("======> NO READ PERMISSIONS FOR FILE!\n"); /* sanity check */
182                 /* Send the client a 403 Forbidden */
183
184                 send(clients[n], "HTTP/1.0 403 Forbidden\r\n\r\n", 26, 0);
185                 strcpy(path, home_dir);
186                 strcpy(&path[strlen(home_dir)], FORBIDDEN);
187
188                 /* After changing the pathname to the "forbidden" page, write that page to the client socket. */
189
190                 if( (fd = open(path, O_RDONLY)) != -1){
191                         while( (bytes_read = read(fd, data_to_send, 1024)) > 0){
192                                 write(clients[n], data_to_send, bytes_read);
193                         }
194                 }
195         }

I thought this would be enough, but it's not. I can see two things being wrong here:

  • My entry condition, errno == EACCES. Since this is a multiprocess webserver, would this be a "safe" and correct way of checking errno's value? Is there a better way?
  • Do I still need to send() a "301 Moved Permanently\nLocation: "? This seems wrong, seeing how what I wanted wasn't moved at all - I just didn't have access to it.

I'd wager that my error is the first one, as it doesn't seem to go into the if at all. Any suggestions would be appreciated.

Was it helpful?

Solution

errno will only by set if stat() failed.

So modifiy your code like this:

    int result = stat(path, &rd_perm); /* path contains the full path to the original file request */
    if ((-1 == result) && (errno == EACCES)) { /* We don't have permissions to view the file... */

Each process has its own instance of errno.

If going multihreaded make sure to compile using option -pthread to have errno being declared as thread-local.

Please note that the compiler option -pthread is different from telling the linker to link against libpthread by giving the linker-option -lpthread.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top