> respond(404, "File not found");
> else if (error)
> respond(500, error.toString());
> else if (stats.isDirectory())
> fs.readdir(path, function(error, files) {
> if (error)
> respond(500, error.toString());
> else
> respond(200, files.join("\n"));
> });
> else
> respond(200, fs.createReadStream(path),
> require("mime").lookup(path));
> });
>};
Поскольку запросы к диску занимают время, >fs.stat
работает асинхронно. Когда файла не существует, >fs.stat
передаст объект >error
с кодовым свойством >"ENOENT"
в функцию обратного вызова. Было бы здорово, если бы Node определил разные типы ошибок для разных ошибок, но такого нет. Вместо этого он выдаёт запутанные коды в стиле Unix.
Все неожиданные ошибки мы будем выдавать с кодом 500, обозначающим, что на сервере проблема – в отличие от кодов, начинающихся на 4, говорящих о проблеме с запросом. В некоторых ситуациях это будет не совсем аккуратно, но для небольшой примерной программы этого будет достаточно.
Объект >stats
возвращаемый >fs.stat
, рассказывает нам о файле всё. Например, >size
– размер файла, >mtime
– дата модификации. Здесь нам нужно узнать, директория это или обычный файл – это нам сообщит метод >isDirectory
.
Для чтения списка файлов в директории мы используем >fs.readdir
, и через ещё один обратный вызов, возвращаем его пользователю. Для обычных файлов мы создаём читаемый поток через >fs.createReadStream
и передаём его в ответ, вместе с типом содержимого, который модуль >"mime"
выдал для этого файла.
Код обработки >DELETE
будет проще:
>methods.DELETE = function(path, respond) {
> fs.stat(path, function(error, stats) {
> if (error && error.code == "ENOENT")
> respond(204);
> else if (error)
> respond(500, error.toString());
> else if (stats.isDirectory())
> fs.rmdir(path, respondErrorOrNothing(respond));
> else
> fs.unlink(path, respondErrorOrNothing(respond));
> });
>};
Возможно, вам интересно, почему попытка удаления несуществующего файла возвращает статус 204 вместо ошибки. Можно сказать, что при попытке удалить несуществующий файл, так как файла там уже нет, то запрос уже исполнен. Стандарт HTTP поощряет людей делать идемпотентные запросы – то есть такие, при которых многократный повтор одного и того же действия не приводит к разным результатам.
>function respondErrorOrNothing(respond) {
> return function(error) {
> if (error)
> respond(500, error.toString());
> else
> respond(204);
> };
>}
Когда ответ HTTP не содержит данных, можно использовать код статуса 204 (“no content”). Так как нам нужно обеспечить функции обратного вызова, которые либо сообщают об ошибки, или возвращают ответ 204 в разных ситуациях, я написал специальную функцию