установка gzip устанавливает метку времени из Python

Это, вероятно, проблема с кешем. В консоли сетевого браузера вы должны увидеть ответ типа 304 Не изменено.

Конечно, вы можете добавить элемент в URL, чтобы обойти кеш:

updates.open('GET','scripts/check_for_notifications.php&nocache=' + new Date().getTime(), true);

Если это работает, вам нужно будет настроить сервер (apache или nginx), чтобы предотвратить кэшируется. Это чище, чем решение с отметкой времени. браузер не хранит кэшированные файлы без необходимости.

Apache .htaccess или Apache conf, что-то вроде


    
        Header set Cache-Control "no-cache, no-store, must-revalidate"
        Header set Pragma "no-cache"
        Header set Expires 0
    

Nginx conf, что-то вроде

location = /check.php {
    add_header 'Cache-Control' 'no-cache, no-store, must-revalidate';
    expires off;
}

Вы также можете увидеть api: https: // hacks.mozilla.org/2016/03/referrer-and-cache-control-apis-for-fetch/

Будьте осторожны с вашим кодом, он может запустить несколько запросов одновременно и найти Если у вас слишком много пользователей, вы можете использовать DOS.

Если запросы занимают более 2 секунд из-за медленной работы сервера, другие запросы тем временем будут отправлены, что еще больше замедлит работу сервера ...

7
задан zaphod 5 November 2008 в 02:50
поделиться

5 ответов

Да, у Вас нет немного довольно опций. Время записано с этой строкой в _write_gzip_header:

write32u(self.fileobj, long(time.time()))

Так как они не дают Вам способ переопределить время, можно сделать одну из этих вещей:

  1. Получите класс из GzipFile и скопируйте _write_gzip_header функционируйте в свой производный класс, но с другим значением в этой строке.
  2. После импорта gzip модуля присвойте новый код его участнику времени. Вы будете по существу предоставлять новое определение времени имени в коде gzip, таким образом, можно будет изменить то, что означает time.time ().
  3. Скопируйте весь gzip модуль, и назовите его my_stable_gzip и измените строку, Вы должны.
  4. Передайте объект CStringIO в как fileobj и измените поток байтов после того, как gzip будет сделан.
  5. Запишите поддельный объект файла, который отслеживает записанные байты, и передает все до реального файла, за исключением байтов для метки времени, которую Вы пишете сами.

Вот пример (непротестированной) опции № 2:

class FakeTime:
    def time(self):
        return 1225856967.109

import gzip
gzip.time = FakeTime()

# Now call gzip, it will think time doesn't change!

Опция № 5 может быть самой чистой с точки зрения не в зависимости от внутренностей gzip (непротестированного) модуля:

class GzipTimeFixingFile:
    def __init__(self, realfile):
        self.realfile = realfile
        self.pos = 0

    def write(self, bytes):
        if self.pos == 4 and len(bytes) == 4:
            self.realfile.write("XYZY")  # Fake time goes here.
        else:
            self.realfile.write(bytes)
        self.pos += len(bytes)
8
ответ дан 6 December 2019 в 12:56
поделиться

Отправьте патч, в котором факторизуется вычисление метки времени. Это было бы почти наверняка принято.

2
ответ дан 6 December 2019 в 12:56
поделиться

В lib/gzip.py мы находим метод, который создает заголовок, включая часть, которая действительно содержит метку времени. В Python 2.5 это начинается на строке 143:

def _write_gzip_header(self):
    self.fileobj.write('\037\213')             # magic header
    self.fileobj.write('\010')                 # compression method
    fname = self.filename[:-3]
    flags = 0
    if fname:
        flags = FNAME
    self.fileobj.write(chr(flags))
    write32u(self.fileobj, long(time.time())) # The current time!
    self.fileobj.write('\002')
    self.fileobj.write('\377')
    if fname:
        self.fileobj.write(fname + '\000')

Как Вы видите, это использует time.time () для выборки текущего времени. Согласно документам модуля онлайн, time.time "возвратит время как число с плавающей точкой, выраженное в секундах с эпохи в UTC". Так, при изменении этого на константу с плавающей точкой выбора можно было всегда выписывать те же заголовки. Я не вижу лучший способ сделать это, если Вы не хотите взломать библиотеку еще немного для принятия дополнительного параметрического усилителя времени, который Вы используете при установке по умолчанию для time.time (), когда это не указано, в этом случае, я уверен, что они любили бы его, если Вы отправили патч!

0
ответ дан 6 December 2019 в 12:56
поделиться

Это не симпатично, но Вы могли monkeypatch time.time временно с чем-то вроде этого:

import time

def fake_time():
  return 100000000.0

def do_gzip(content):
    orig_time = time.time
    time.time = fake_time
    # result = do gzip stuff here
    time.time = orig_time
    return result

Это не симпатично, но это, вероятно, работало бы.

0
ответ дан 6 December 2019 в 12:56
поделиться

Я послушал совет г-на Coventry и отправил патч. Однако, учитывая текущее состояние плана выпуска Python, с 3,0 просто за углом, я не ожидаю, что это обнаружится в выпуске в ближайшее время. Однако, мы будем видеть то, что происходит!

Тем временем мне нравится опция 5 г-на Batchelder передачи по каналу gzip потока через маленький пользовательский фильтр, который устанавливает поле метки времени правильно. Это походит на самый чистый подход. Как он демонстрирует, требуемый код является на самом деле довольно маленьким, хотя его пример действительно зависит для части его простоты на (в настоящее время допустимом) предположении что gzip реализация модуля примет решение записать метку времени, использующую точно один четырехбайтовый вызов для write(). Однако, я не думаю, что было бы очень трудно придумать полностью общую версию в случае необходимости.

Исправляющий обезьяну подход (иначе опция 2) довольно заманчив для ее простоты, но дает мне паузу, потому что я пишу библиотеку, которая звонит gzip, не только автономная программа, и мне кажется, что кто-то мог бы попытаться звонить gzip от другого потока, прежде чем мой модуль готов обратить свое изменение к gzip глобальное состояние модуля. Это было бы особенно неудачно, если бы другой поток пытался вытянуть подобный исправляющий обезьяну трюк! Я признаю, что эта потенциальная проблема не звучит вероятной подойти на практике, но вообразить, как болезненный это должно было бы диагностировать такую путаницу!

Я могу неопределенно предположить пытаться сделать что-то хитрое и сложное и возможно не настолько соответствующий требованиям завтрашнего дня, чтобы так или иначе импортировать частную копию gzip модуль и патч обезьяны, что, но той точкой фильтр кажется более простым и более прямым.

1
ответ дан 6 December 2019 в 12:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: