Longobard
написал 31 марта 2004 года в 00:03 (1034 просмотра)
Ведет себя
как мужчина; открыл 291 тему в форуме, оставил 2499 комментариев на сайте.
У меня такая трабла: мой веб-сервер не показывает размер файла когда его скачиваешь. То есть клиент не может узнать этот размер. Я зачитал до дыр RFC2068, но так и не узнал, каким макаром этот самый размер клиенту указать. Как это сделать? Например есть файл test.tar.bz2 и лежит он в корне. Сервер получает запрос GET /test.tar.bz2 HTTP/1.0. Сервер успешно отсылает файл и он скачиается. Однако ни один браузер (Пробовал Оперу, Мазилу, Конкуерор) не определяют его размер при скачивании. Чего делать?
Последние комментарии
-
OlegL, 17 декабря 2023 года в 15:00 →
Перекличка
21
-
REDkiy, 8 июня 2023 года в 9:09 →
Как «замокать» файл для юниттеста в Python?
2
-
fhunter, 29 ноября 2022 года в 2:09 →
Проблема с NO_PUBKEY: как получить GPG-ключ и добавить его в базу apt?
6
-
Иванн, 9 апреля 2022 года в 8:31 →
Ассоциация РАСПО провела первое учредительное собрание
1
-
Kiri11.ADV1, 7 марта 2021 года в 12:01 →
Логи catalina.out в TomCat 9 в формате JSON
1
DevOps as a Service from Palark
24/7 SRE & DevOps service to cover all your Kubernetes needs.

При этом серверу не приходит какого-либо запроса. То есть я поставил логирование всего что приходит в сокет серверу — так там сплошной GET и при закачке файла посылается только один запрос по типу GET /test.tar.bz2 HTTP/1.1
Ну что тебе сказать… Все правильно, по запросу GET /test.tar.bz2 HTTP/1.1 и приходит размер файла от Апача, протокол требует. Просто ты полного ответа сервера не видишь, вот и кажется, что не приходит…
А ты сделай вот что:
->telnet 127.0.0.1 80
Trying 127.0.0.1…
Connected to 127.0.0.1.
Escape character is '^]’.
->GET /test.bb HTTP/1.1
->Host: 127.0.0.1
->
HTTP/1.1 200 OK
Date: Tue, 30 Mar 2004 23:02:14 GMT
Server: Apache/1.3.29 (Unix)
Last-Modified: Tue, 30 Mar 2004 22:06:59 GMT
ETag: «1a39b-b-4069ef83»
Accept-Ranges: bytes
Content-Length: 11
Content-Type: text/plain
yalabubuda
Connection closed by foreign host.
Здесь «->» обозначает строку введенную с терминала и закончившуюся Enter’ом. Обрати внимание на строку «Content-Length: 11» в ответе сервера. Это — размер моего тестового файла test.bb, который содержит лишь строку «yalabubuda»
Все это в RFC 2068…
Good Luck,
UT
Есть ещё запрос HEAD, который, в отличие от GET, отдаёт только заголовки, как раз те, которые являются «server reply». Начинаются они всегда «HTTP/1.x xxx …..»
Все, ясно, всем спасибо. Проглядел я это как-то в RFC2068 :(
Хм. Выяснилсь что у меня RFC было неполным. У меня в нем только 9 глав было, а об этом рассказывается в главе номер 14 :)
А как узнать MIME-тип файла (например text/plain и т.д.). Наверняка ведь есть функция какая-то. Не по расширению мне ведь определять. И как получается ETag?
Как его сгенерить? Что он из себя представляет? Контрольную сумму файла?
Апач этот етаг генерит так:
char *etag; char *weak; core_dir_config *cfg; etag_components_t etag_bits; cfg = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); etag_bits = (cfg->etag_bits & (~ cfg->etag_remove)) | cfg->etag_add; if (etag_bits == ETAG_UNSET) { etag_bits = ETAG_BACKWARD; } /* * Make an ETag header out of various pieces of information. We use * the last-modified date and, if we have a real file, the * length and inode number - note that this doesn't have to match * the content-length (i.e. includes), it just has to be unique * for the file. * * If the request was made within a second of the last-modified date, * we send a weak tag instead of a strong one, since it could * be modified again later in the second, and the validation * would be incorrect. */ weak = ((r->request_time - r->mtime > 1) && !force_weak) ? "" : "W/"; if (r->finfo.st_mode != 0) { char **ent; array_header *components; int i; /* * If it's a file (or we wouldn't be here) and no ETags * should be set for files, return an empty string and * note it for ap_send_header_field() to ignore. */ if (etag_bits & ETAG_NONE) { ap_table_setn(r->notes, "no-etag", "omit"); return ""; } components = ap_make_array(r->pool, 4, sizeof(char *)); if (etag_bits & ETAG_INODE) { ent = (char **) ap_push_array(components); *ent = ap_psprintf(r->pool, "%lx", (unsigned long) r->finfo.st_ino); } if (etag_bits & ETAG_SIZE) { ent = (char **) ap_push_array(components); *ent = ap_psprintf(r->pool, "%lx", (unsigned long) r->finfo.st_size); } if (etag_bits & ETAG_MTIME) { ent = (char **) ap_push_array(components); *ent = ap_psprintf(r->pool, "%lx", (unsigned long) r->mtime); } ent = (char **) components->elts; etag = ap_pstrcat(r->pool, weak, "\"", NULL); for (i = 0; i < components->nelts; ++i) { etag = ap_psprintf(r->pool, "%s%s%s", etag, (i == 0 ? "" : "-"), ent[i]); } etag = ap_pstrcat(r->pool, etag, "\"", NULL); } else { etag = ap_psprintf(r->pool, "%s\"%lx\"", weak, (unsigned long) r->mtime); } return etag;