Создаете простой HTTP-сервер, используя errno, чтобы ответить "403 Forbidden", а затем перенаправить на страницу 403?

Я делаю простой HTTP веб-сервер, и это соответствующая часть кода:

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         }

Я думал, что этого будет достаточно, но это не так. Я вижу две вещи, которые здесь не так:

  • Мое условие входа, errno == EACCES, Поскольку это многопроцессорный веб-сервер, будет ли это "безопасным" и правильным способом проверки значения errno? Есть ли способ лучше?
  • Нужно ли отправлять () сообщение "301 перемещено навсегда \n Расположение: "? Это кажется неправильным, видя, что то, что я хотел, не было перемещено вообще - у меня просто не было доступа к нему.

Держу пари, что моя ошибка - первая, так как она, похоже, не if совсем. Мы ценим любые предложения.

1 ответ

Решение

errno будет только установленным, если stat() не удалось.

Поэтому измените ваш код следующим образом:

    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... */

Каждый процесс имеет свой экземпляр errno,

Если вы используете многопоточность, обязательно скомпилируйте опцию -pthread иметь errno будучи объявленным как локальный поток.

Обратите внимание, что опция компилятора -pthread отличается от указания компоновщику ссылаться на libpthread предоставив опцию компоновщика -lpthread,

Другие вопросы по тегам