| 288 | // ��� gzip ��������� |
| 289 | |
| 290 | bool http_client::write_gzip_trailer(ostream& out) |
| 291 | { |
| 292 | #ifdef HAVE_BIG_ENDIAN |
| 293 | struct gztrailer { |
| 294 | unsigned char crc32_[4]; |
| 295 | unsigned char zlen_[4]; |
| 296 | }; |
| 297 | struct gztrailer trailer; |
| 298 | |
| 299 | trailer.crc32_[0] = (u_char) (gzip_crc32_ & 0xff); |
| 300 | trailer.crc32_[1] = (u_char) ((gzip_crc32_ >> 8) & 0xff); |
| 301 | trailer.crc32_[2] = (u_char) ((gzip_crc32_ >> 16) & 0xff); |
| 302 | trailer.crc32_[3] = (u_char) ((gzip_crc32_ >> 24) & 0xff); |
| 303 | |
| 304 | trailer.zlen_[0] = (u_char) (gzip_total_in_ & 0xff); |
| 305 | trailer.zlen_[1] = (u_char) ((gzip_total_in_ >> 8) & 0xff); |
| 306 | trailer.zlen_[2] = (u_char) ((gzip_total_in_ >> 16) & 0xff); |
| 307 | trailer.zlen_[3] = (u_char) ((gzip_total_in_ >> 24) & 0xff); |
| 308 | #else |
| 309 | struct gztrailer { |
| 310 | unsigned int crc32_; |
| 311 | unsigned int zlen_; |
| 312 | }; |
| 313 | |
| 314 | struct gztrailer trailer; |
| 315 | trailer.crc32_ = gzip_crc32_; |
| 316 | trailer.zlen_ = gzip_total_in_; |
| 317 | |
| 318 | #endif // HAVE_BIG_ENDIAN |
| 319 | |
| 320 | // �鴫�䷽ʽ��� gzip β |
| 321 | if (chunked_transfer_) { |
| 322 | return write_chunk(out, &trailer, sizeof(trailer)) |
| 323 | && write_chunk_trailer(out); |
| 324 | } |
| 325 | |
| 326 | // ��ͨ��ʽ��� gzip β |
| 327 | if (out.write(&trailer, sizeof(trailer)) < 0) { |
| 328 | disconnected_ = true; |
| 329 | return false; |
| 330 | } else { |
| 331 | return true; |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | bool http_client::write_head(const http_header& header) |
| 336 | { |