Отправка 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));
}