Отправка gzipped-данных в WebRequest?

У меня есть большой объем данных (~ 100k), которые мое приложение С# отправляет на мой сервер Apache с установленным mod_gzip. Сначала я пытаюсь выполнить gzip, используя System.IO.Compression.GZipStream. PHP получает необработанные gzipped данные, поэтому Apache не разжимает его, как я ожидал. Я что-то пропустил?

System.Net.WebRequest req = WebRequest.Create(this.Url);
req.Method = this.Method; // "post"
req.Timeout = this.Timeout;
req.ContentType = "application/x-www-form-urlencoded";
req.Headers.Add("Content-Encoding: gzip");

System.IO.Stream reqStream = req.GetRequestStream();

GZipStream gz = new GZipStream(reqStream, CompressionMode.Compress);

System.IO.StreamWriter sw = new System.IO.StreamWriter(gz, Encoding.ASCII);
sw.Write( large_amount_of_data );
sw.Close();

gz.Close();
reqStream.Close()


System.Net.WebResponse resp = req.GetResponse();
// (handle response...)

Я не совсем уверен, что "Content-Encoding: gzip" применяется к поставляемым клиентам заголовкам.

Ответы

Ответ 1

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

Ответ 2

Что касается вашего вопроса, применимо ли Content-Encoding к поставляемым клиентам заголовкам - согласно стандарт HTTP/1.1, это:

(из раздела 7)

Запросы и ответные сообщения МОГУТ переносить сущность, если иное не ограничивается методом запроса или кодом статуса ответа.

(из раздела 7.1)

   entity-header  = Allow                    ; Section 14.7
                  | Content-Encoding         ; Section 14.11
                  | Content-Language         ; Section 14.12
                  | Content-Length           ; Section 14.13
                  | Content-Location         ; Section 14.14
                  | Content-MD5              ; Section 14.15
                  | Content-Range            ; Section 14.16
                  | Content-Type             ; Section 14.17
                  | Expires                  ; Section 14.21
                  | Last-Modified            ; Section 14.29
                  | extension-header

Ответ 3

Вам нужно изменить

req.Headers.Add("Content-Encoding: gzip");

к

req.Headers.Add("Content-Encoding","gzip");

Ответ 4

Согласно http://www.dominoexperts.com/articles/GZip-servlet-to-gzip-your-pages

Вы должны установитьContentType() в исходный формат, как вы это делаете с приложением /x -www-form-urlencoded. Тогда...

 // See if browser can handle gzip
 String encoding=req.getHeader("Accept-Encoding");
 if (encoding != null && encoding.indexOf("gzip") >=0 ) {  // gzip browser 
      res.setHeader("Content-Encoding","gzip");
      OutputStream o=res.getOutputStream();
      GZIPOutputStream gz=new GZIPOutputStream(o);
      gz.write(content.getBytes());
      gz.close();
      o.close();
            } else {  // Some old browser -> give them plain text.                        PrintWriter o = res.getWriter();
                    o.println(content);
                    o.flush();
                    o.close();
            }

Ответ 5

На стороне PHP это отделяет верхний и нижний колонтитулы от файла

function gzip_stream_uncompress($data) { return gzinflate(substr($data, 10, -8)); }