Шаг 28 - 500 Internal Server Error

Если Вы хоть раз натыкались на эту ошибку во время разработки скрипта, то Вы счастливый человек :) Скорее "счастливый"... Эта ошибка прямой показатель Вашего стремления освоить CGI. Если человек не представляет себе о ее существовании, и при этом утверждает, что он "гуру" в этом деле, то готовьте для него корзину тухлых помидоров.

Вода... Водичка... А теперь к делу :) Ошибка эта дословно переводится как "Внутренняя Ошибка Сервера" (знатоки забугорного если что подправят :) Люди разрабатывающие веб-сервер делают это мно-о-о-го лет, поэтому можно утверждать на 99,9%, что внутри его ошибок нет :) По крайней мере вызывающих такой конкретный отказ в работе, как ошибка 500. Ошибка эта может произойти только в случае некорректной работы вашего скрипта. Насколько некорректной сейчас разберемся...

У меня вопрос: Вы знаете как узнать от чего произошла ошибка ?! Уверен, что 50% новичков (не хочу говорить о профях) скажет что незнает... И правильно скажет, иначе не было бы этого шага :) Хочу Вас научить один единственный раз откуда получать такую конфиденциальную информацию. Правильно (или Вы еще не сообразили ?), из файла /logs/error.log (или схожего по названию).

Получили мы ошибку 500... Что делать ? Идем в файл error.log и смотрим в последнюю строку... У меня почти всегда одна и таже ошибка, вот примерно такая...

[Sat Oct 21 10:00:00 2000] [error] [client 123.45.67.89] Premature end of script headers: с:/apache/cgi-bin/1.cgi

Заметьте то, что сервер не скрывает от Вас ничего и прямо говорит "Ну типа у меня тут Premature end of script headers, и ваще отстань... 500...". Берем "забугорно-местный" переводчик и получаем нечто похожее на "неожиданный конец заголовка скрипта".

И что ? Мысли есть ? Так вот теперь почему это происходит (во многих случаях). Вы попросту неправильно составили заголовок ответа. Заголовок должен быть отделен от содержимого пустой строкой. Например, вместо:

	printf("Content-type: text/html\n\n");

Вы написали строку с одной \n:

	printf("Content-type: text/html\n");
Также результатом этой ошибки может быть (а скорее всего и есть) неправильное окончание программы. Например, когда программа выполняется правильно после завершения она всегда дает знать системе, что она выполнилась на отлично, а в баллах системы на 0 :) После аварийного же завершения программы система не получает ответа равного 0, и поэтому это является прямым признаком ошибки.

В Линуксе есть другая проблема. Если Вы неправильно работаете с динамической памятью, то программа сразу же вываливается с сообщением:

	Segmentation fault

А если присмотреться, то данная строка совсем не похожа на "Content-type:". Отсюда ошибка 500 о неправильном заголовке ответа.

Также из личного опыта, но это явление я объяснить не могу... Скрипты конкретно вываливаются и все тут. Десяти разовая проверка не дает результата. И тут приходит мысля о том, чтобы поменять местами участки считывания данных из stdin и вывод в stdout. Например, если Вы сначала считывали, то теперь просто сначала выведите "Content-type: ...\n\n", а потом считывайте. Незнаю почему, но иногда помогает. Объяснить ничем не могу, разве только тем, что Апач у меня в Линуксе старенький и видимо у него не все дома в этот момент...

При разработке скрипта на любом языке очень аккуратно подходите к динамической памяти. Неправильно инициализированная переменная приводит к невероятным результатам.

Теперь немного о том, что пишут на эту тему профессионалы (с моим фривольным разбавлением) :

Вобщем такие пироги. Некоторым они уже "поперек горла", но как же без них. Самое главное ничего не бояться и везде совать свой нос :)


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Кузин Андрей.