Lines 1406-1414
Link Here
|
1406 |
|
1406 |
|
1407 |
|
1407 |
|
1408 |
/** |
1408 |
/** |
1409 |
* Check for compression |
1409 |
* Check if browser allows compression |
1410 |
*/ |
1410 |
*/ |
1411 |
private boolean isCompressable() { |
1411 |
private boolean isCompressableBrowser() { |
1412 |
|
1412 |
|
1413 |
// Nope Compression could works in HTTP 1.0 also |
1413 |
// Nope Compression could works in HTTP 1.0 also |
1414 |
// cf: mod_deflate |
1414 |
// cf: mod_deflate |
Lines 1425-1438
Link Here
|
1425 |
|| (acceptEncodingMB.indexOf("gzip") == -1)) |
1425 |
|| (acceptEncodingMB.indexOf("gzip") == -1)) |
1426 |
return false; |
1426 |
return false; |
1427 |
|
1427 |
|
1428 |
// Check if content is not allready gzipped |
|
|
1429 |
MessageBytes contentEncodingMB = |
1430 |
response.getMimeHeaders().getValue("Content-Encoding"); |
1431 |
|
1432 |
if ((contentEncodingMB != null) |
1433 |
&& (contentEncodingMB.indexOf("gzip") != -1)) |
1434 |
return false; |
1435 |
|
1436 |
// If force mode, allways compress (test purposes only) |
1428 |
// If force mode, allways compress (test purposes only) |
1437 |
if (compressionLevel == 2) |
1429 |
if (compressionLevel == 2) |
1438 |
return true; |
1430 |
return true; |
Lines 1450-1455
Link Here
|
1450 |
return false; |
1442 |
return false; |
1451 |
} |
1443 |
} |
1452 |
} |
1444 |
} |
|
|
1445 |
// noCompressionUserAgents == null |
1446 |
return true; |
1447 |
} |
1448 |
|
1449 |
|
1450 |
/** |
1451 |
* Check if response allows compression |
1452 |
*/ |
1453 |
private boolean isCompressableResponse() { |
1454 |
|
1455 |
// Check if content is not allready gzipped |
1456 |
MessageBytes contentEncodingMB = |
1457 |
response.getMimeHeaders().getValue("Content-Encoding"); |
1458 |
|
1459 |
if ((contentEncodingMB != null) |
1460 |
&& (contentEncodingMB.indexOf("gzip") != -1)) |
1461 |
return false; |
1462 |
|
1463 |
// If force mode, allways compress (test purposes only) |
1464 |
if (compressionLevel == 2) |
1465 |
return true; |
1453 |
|
1466 |
|
1454 |
// Check if suffisant len to trig the compression |
1467 |
// Check if suffisant len to trig the compression |
1455 |
long contentLength = response.getContentLengthLong(); |
1468 |
long contentLength = response.getContentLengthLong(); |
Lines 1461-1467
Link Here
|
1461 |
response.getContentType())); |
1474 |
response.getContentType())); |
1462 |
} |
1475 |
} |
1463 |
} |
1476 |
} |
1464 |
|
1477 |
// contentLength is too short |
1465 |
return false; |
1478 |
return false; |
1466 |
} |
1479 |
} |
1467 |
|
1480 |
|
Lines 1502-1519
Link Here
|
1502 |
contentDelimitation = true; |
1515 |
contentDelimitation = true; |
1503 |
} |
1516 |
} |
1504 |
|
1517 |
|
|
|
1518 |
MimeHeaders headers = response.getMimeHeaders(); |
1519 |
|
1505 |
// Check for compression |
1520 |
// Check for compression |
1506 |
boolean useCompression = false; |
1521 |
boolean useCompression = false; |
1507 |
if (entityBody && (compressionLevel > 0)) { |
1522 |
if (entityBody && (compressionLevel > 0)) { |
1508 |
useCompression = isCompressable(); |
1523 |
if (isCompressableResponse()) { |
|
|
1524 |
// if the response might be compressable for some browsers, it |
1525 |
// gets a Vary header in any case, so that both versions can be |
1526 |
// cached in parallel. This prevents uncompressed versions in |
1527 |
// caches from being delivered to compression-capable clients. |
1528 |
MessageBytes varyHeader = headers.getValue("Vary"); |
1529 |
if (varyHeader == null) { |
1530 |
// no Vary header yet |
1531 |
headers.addValue("Vary").setString("Accept-Encoding"); |
1532 |
} else { |
1533 |
String vary = varyHeader.toString(); |
1534 |
if (! vary.equals("*")) { |
1535 |
varyHeader.setString(vary + ",Accept-Encoding"); |
1536 |
// this can add a duplicate entry in case |
1537 |
// someone sets Accept-Encoding on an |
1538 |
// uncompressed response, but this situation |
1539 |
// seems so strange (and the result so |
1540 |
// harmless) that it does not seem worth it to |
1541 |
// try to recognize whether Accept-Encoding is |
1542 |
// already present (which seems to require a |
1543 |
// regexp to be exact) |
1544 |
} |
1545 |
// if vary.equals(*), this header does not change |
1546 |
} |
1509 |
|
1547 |
|
1510 |
// Change content-length to -1 to force chunking |
1548 |
useCompression = isCompressableBrowser(); |
1511 |
if (useCompression) { |
1549 |
|
1512 |
response.setContentLength(-1); |
1550 |
// Change content-length to -1 to force chunking |
|
|
1551 |
if (useCompression) { |
1552 |
response.setContentLength(-1); |
1553 |
} |
1513 |
} |
1554 |
} |
1514 |
} |
1555 |
} |
1515 |
|
1556 |
|
1516 |
MimeHeaders headers = response.getMimeHeaders(); |
|
|
1517 |
if (!entityBody) { |
1557 |
if (!entityBody) { |
1518 |
response.setContentLength(-1); |
1558 |
response.setContentLength(-1); |
1519 |
} else { |
1559 |
} else { |
Lines 1549-1556
Link Here
|
1549 |
if (useCompression) { |
1589 |
if (useCompression) { |
1550 |
outputBuffer.addActiveFilter(outputFilters[Constants.GZIP_FILTER]); |
1590 |
outputBuffer.addActiveFilter(outputFilters[Constants.GZIP_FILTER]); |
1551 |
headers.setValue("Content-Encoding").setString("gzip"); |
1591 |
headers.setValue("Content-Encoding").setString("gzip"); |
1552 |
// Make Proxies happy via Vary (from mod_deflate) |
1592 |
|
1553 |
headers.setValue("Vary").setString("Accept-Encoding"); |
1593 |
MessageBytes eTagHeader = headers.getValue("ETag"); |
|
|
1594 |
if (eTagHeader != null) { |
1595 |
String eTag = eTagHeader.toString(); |
1596 |
final int l = eTag.length(); |
1597 |
if (l >= 1 && eTag.charAt(l-1) == '"') { |
1598 |
// quoted ETag - add marker before the closing quote |
1599 |
eTag = eTag.substring(0, l-1) |
1600 |
+ "-gz" |
1601 |
+ eTag.substring(l-1, l); |
1602 |
} else { |
1603 |
// unquoted ETag - should not happen |
1604 |
// FIXME: throw an exception in this case |
1605 |
eTag = eTag + "-gz"; |
1606 |
} |
1607 |
eTagHeader.setString(eTag); |
1608 |
} |
1554 |
} |
1609 |
} |
1555 |
|
1610 |
|
1556 |
// Add date header |
1611 |
// Add date header |