2 This file is part of the KDE libraries
3 Copyright (c) 2002 Waldo Bastian <bastian@kde.org>
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
20 #include "httpfilter.h"
22 #include <kio/global.h>
28 HTTPFilterBase::HTTPFilterBase()
33 HTTPFilterBase::~HTTPFilterBase()
39 HTTPFilterBase::chain(HTTPFilterBase
*previous
)
42 connect(last
, SIGNAL(output(const QByteArray
&)),
43 this, SLOT(slotInput(const QByteArray
&)));
46 HTTPFilterChain::HTTPFilterChain()
52 HTTPFilterChain::addFilter(HTTPFilterBase
*filter
)
60 disconnect(last
, SIGNAL(output(const QByteArray
&)), 0, 0);
64 connect(filter
, SIGNAL(output(const QByteArray
&)),
65 this, SIGNAL(output(const QByteArray
&)));
66 connect(filter
, SIGNAL(error(int, const QString
&)),
67 this, SIGNAL(error(int, const QString
&)));
71 HTTPFilterChain::slotInput(const QByteArray
&d
)
79 HTTPFilterMD5::HTTPFilterMD5()
86 return QLatin1String(context
.base64Digest());
90 HTTPFilterMD5::slotInput(const QByteArray
&d
)
97 HTTPFilterGZip::HTTPFilterGZip()
101 bHasFinished
= false;
105 zstr
.next_in
= (Bytef
*) Z_NULL
;
107 zstr
.zalloc
= Z_NULL
;
109 zstr
.opaque
= Z_NULL
;
110 inflateInit2(&zstr
, -MAX_WBITS
);
115 HTTPFilterGZip::~HTTPFilterGZip()
123 /* The get_byte() and checkHeader() functions are modified version from */
124 /* the correpsonding functions that can be found in zlib, the following */
125 /* copyright notice applies to these functions: */
127 /* zlib.h -- interface of the 'zlib' general purpose compression library
128 version 1.1.3, July 9th, 1998
130 Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
132 This software is provided 'as-is', without any express or implied
133 warranty. In no event will the authors be held liable for any damages
134 arising from the use of this software.
136 Permission is granted to anyone to use this software for any purpose,
137 including commercial applications, and to alter it and redistribute it
138 freely, subject to the following restrictions:
140 1. The origin of this software must not be misrepresented; you must not
141 claim that you wrote the original software. If you use this software
142 in a product, an acknowledgment in the product documentation would be
143 appreciated but is not required.
144 2. Altered source versions must be plainly marked as such, and must not be
145 misrepresented as being the original software.
146 3. This notice may not be removed or altered from any source distribution.
148 Jean-loup Gailly Mark Adler
149 jloup@gzip.org madler@alumni.caltech.edu
152 The data format used by the zlib library is described by RFCs (Request for
153 Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
154 (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
158 HTTPFilterGZip::get_byte()
161 if (bEof
) return EOF
;
162 if (zstr
.avail_in
== 0)
169 return *(zstr
.next_in
)++;
177 static int gz_magic
[2] = {0x1f, 0x8b}; /* gzip magic header */
180 #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
181 #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
182 #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
183 #define ORIG_NAME 0x08 /* bit 3 set: original file name present */
184 #define COMMENT 0x10 /* bit 4 set: file comment present */
185 #define RESERVED 0xE0 /* bits 5..7: reserved */
192 HTTPFilterGZip::checkHeader()
198 /* Check the gzip magic header */
199 for (len
= 0; len
< 2; ++len
) {
201 if (c
!= gz_magic
[len
]) {
215 int method
= get_byte(); /* method byte */
216 int flags
= get_byte(); /* flags byte */
218 if (method
!= Z_DEFLATED
|| (flags
& RESERVED
) != 0) {
222 /* Discard time, xflags and OS code: */
223 for (len
= 0; len
< 6; ++len
) (void)get_byte();
225 if ((flags
& EXTRA_FIELD
) != 0) { /* skip the extra field */
226 len
= (uInt
)get_byte();
227 len
+= ((uInt
)get_byte())<<8;
228 /* len is garbage if EOF but the loop below will quit anyway */
229 while (len
-- != 0 && get_byte() != EOF
) ;
231 if ((flags
& ORIG_NAME
) != 0) { /* skip the original file name */
232 while ((c
= get_byte()) != 0 && c
!= EOF
) ;
234 if ((flags
& COMMENT
) != 0) { /* skip the .gz file comment */
235 while ((c
= get_byte()) != 0 && c
!= EOF
) ;
237 if ((flags
& HEAD_CRC
) != 0) { /* skip the header crc */
238 for (len
= 0; len
< 2; ++len
) (void)get_byte();
248 HTTPFilterGZip::slotInput(const QByteArray
&d
)
262 // Make sure we get the last bytes still in the pipe.
263 // Needed with "deflate".
264 QByteArray
flush(4, 0);
266 if (!bHasFinished
&& !bHasHeader
)
269 emit
output(headerData
);
272 emit
output(QByteArray());
276 emit
error( KIO::ERR_SLAVE_DEFINED
, i18n("Unexpected end of data, some information may be lost."));
284 iTrailer
-= d
.size();
289 emit
output(QByteArray());
298 // Add data to header.
299 int orig_size
= headerData
.size();
300 headerData
.resize(orig_size
+d
.size());
301 memcpy(headerData
.data()+orig_size
, d
.data(), d
.size());
303 zstr
.avail_in
= headerData
.size();
304 zstr
.next_in
= (Bytef
*) headerData
.data();
306 int result
= checkHeader();
315 return; // next time better
321 zstr
.avail_in
= d
.size();
322 zstr
.next_in
= (Bytef
*) d
.data();
325 while( zstr
.avail_in
)
328 zstr
.next_out
= (Bytef
*) buf
;
329 zstr
.avail_out
= 8192;
330 int result
= inflate( &zstr
, Z_NO_FLUSH
);
331 if ((result
!= Z_OK
) && (result
!= Z_STREAM_END
))
333 emit
error( KIO::ERR_SLAVE_DEFINED
, i18n("Receiving corrupt data."));
336 int bytesOut
= 8192 - zstr
.avail_out
;
339 QByteArray
d( buf
, bytesOut
);
342 if (result
== Z_STREAM_END
)
352 emit
output(QByteArray());
360 HTTPFilterDeflate::HTTPFilterDeflate()
368 #include "httpfilter.moc"