use of com.helger.http.QValue in project ph-web by phax.
the class UnifiedResponse method applyToResponse.
public final void applyToResponse(@Nonnull final HttpServletResponse aHttpResponse) throws IOException {
ValueEnforcer.notNull(aHttpResponse, "HttpResponse");
// Apply all collected headers
for (final Map.Entry<String, ICommonsList<String>> aEntry : m_aResponseHeaderMap) {
final String sHeaderName = aEntry.getKey();
int nIndex = 0;
for (final String sHeaderValue : aEntry.getValue()) {
// Ensure single line values
final String sUnifiedHeaderValue = m_bHttpHeaderValuesUnified ? HttpHeaderMap.getUnifiedValue(sHeaderValue, m_bHttpHeaderValuesQuoteIfNecessary) : sHeaderValue;
if (nIndex == 0)
aHttpResponse.setHeader(sHeaderName, sUnifiedHeaderValue);
else
aHttpResponse.addHeader(sHeaderName, sUnifiedHeaderValue);
++nIndex;
}
}
final boolean bIsRedirect = isRedirectDefined();
final boolean bHasStatusCode = isStatusCodeDefined();
if (bIsRedirect) {
if (bHasStatusCode)
logWarn("Ignoring provided status code because a redirect is specified!");
if (!m_bAllowContentOnRedirect) {
if (m_aCacheControl != null)
logInfo("Ignoring provided Cache-Control because a redirect is specified!");
if (m_sContentDispositionFilename != null)
logWarn("Ignoring provided Content-Dispostion filename because a redirect is specified!");
if (m_aMimeType != null)
logWarn("Ignoring provided MimeType because a redirect is specified!");
if (m_aCharset != null)
logWarn("Ignoring provided charset because a redirect is specified!");
if (hasContent())
logWarn("Ignoring provided content because a redirect is specified!");
}
// Note: After using this method, the response should be
// considered to be committed and should not be written to.
String sRealTargetURL;
if (ServletSettings.isEncodeURLs()) {
try {
sRealTargetURL = aHttpResponse.encodeRedirectURL(m_sRedirectTargetUrl);
} catch (final IllegalArgumentException ex) {
// Happens e.g. if "http://server/../" is requested
LOGGER.warn("Failed to encode redirect target URL '" + m_sRedirectTargetUrl + "': " + ex.getMessage());
sRealTargetURL = m_sRedirectTargetUrl;
}
} else
sRealTargetURL = m_sRedirectTargetUrl;
if (LOGGER.isDebugEnabled())
LOGGER.debug("Response is a redirect to '" + sRealTargetURL + "' using mode " + m_eRedirectMode);
switch(m_eRedirectMode) {
case DEFAULT:
aHttpResponse.sendRedirect(sRealTargetURL);
break;
case POST_REDIRECT_GET:
if (m_eHttpVersion.is10()) {
// For HTTP 1.0 send 302
aHttpResponse.setStatus(HttpServletResponse.SC_FOUND);
} else {
// For HTTP 1.1 send 303
aHttpResponse.setStatus(HttpServletResponse.SC_SEE_OTHER);
}
// Set the location header
aHttpResponse.addHeader(CHttpHeader.LOCATION, sRealTargetURL);
break;
default:
throw new IllegalStateException("Unimplemented redirect mode " + m_eRedirectMode + "!");
}
if (!m_bAllowContentOnRedirect)
return;
}
if (bHasStatusCode) {
if (bIsRedirect)
logWarn("Overriding provided redirect because a status code is specified!");
if (!m_bAllowContentOnStatusCode) {
if (m_aCacheControl != null)
logInfo("Ignoring provided Cache-Control because a status code is specified!");
if (m_sContentDispositionFilename != null)
logWarn("Ignoring provided Content-Dispostion filename because a status code is specified!");
if (m_aMimeType != null)
logWarn("Ignoring provided MimeType because a status code is specified!");
if (m_aCharset != null)
logWarn("Ignoring provided charset because a status code is specified!");
if (hasContent())
logWarn("Ignoring provided content because a status code is specified!");
}
if (m_nStatusCode == HttpServletResponse.SC_UNAUTHORIZED && !m_aResponseHeaderMap.containsHeaders(CHttpHeader.WWW_AUTHENTICATE))
logWarn("Status code UNAUTHORIZED (401) is returned, but no " + CHttpHeader.WWW_AUTHENTICATE + " HTTP response header is set!");
// Content may be present so, sendError is not an option here!
if (m_nStatusCode >= HttpServletResponse.SC_BAD_REQUEST && m_aContentArray == null) {
// It's an error
// Note: After using this method, the response should be considered
// to be committed and should not be written to.
aHttpResponse.sendError(m_nStatusCode);
} else {
// It's a status message "only"
// Note: The container clears the buffer and sets the Location
// header, preserving cookies and other headers.
aHttpResponse.setStatus(m_nStatusCode);
}
if (!m_bAllowContentOnStatusCode)
return;
if (!hasContent()) {
// continue - would produce some warnings
return;
}
}
// Verify only if is a response with content
_verifyCachingIntegrity();
if (m_aCacheControl != null) {
final String sCacheControlValue = m_aCacheControl.getAsHTTPHeaderValue();
if (StringHelper.hasText(sCacheControlValue))
aHttpResponse.setHeader(CHttpHeader.CACHE_CONTROL, sCacheControlValue);
else
logWarn("An empty Cache-Control was provided!");
}
if (m_sContentDispositionFilename != null) {
final StringBuilder aSB = new StringBuilder();
if (m_aRequestBrowserInfo != null && m_aRequestBrowserInfo.getBrowserType() == EBrowserType.IE && m_aRequestBrowserInfo.getVersion().getMajor() <= 8) {
// Special case for IE <= 8
final Charset aCharsetToUse = m_aCharset != null ? m_aCharset : StandardCharsets.UTF_8;
aSB.append(m_eContentDispositionType.getID()).append("; filename=").append(URLHelper.urlEncode(m_sContentDispositionFilename, aCharsetToUse));
} else {
// Filename needs to be surrounded with double quotes (single quotes
// don't work).
aSB.append(m_eContentDispositionType.getID()).append("; filename=\"").append(m_sContentDispositionFilename).append('"');
// Check if we need an UTF-8 filename
// http://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter-of-content-disposition-header-in-http/6745788#6745788
final String sRFC5987Filename = RFC5987Encoder.getRFC5987EncodedUTF8(m_sContentDispositionFilename);
if (!sRFC5987Filename.equals(m_sContentDispositionFilename))
aSB.append("; filename*=UTF-8''").append(sRFC5987Filename);
}
aHttpResponse.setHeader(CHttpHeader.CONTENT_DISPOSITION, aSB.toString());
if (m_aMimeType == null) {
logWarn("Content-Disposition is specified but no MimeType is set. Using the default download MimeType.");
aHttpResponse.setContentType(CMimeType.APPLICATION_FORCE_DOWNLOAD.getAsString());
}
}
// Mime type
if (m_aMimeType != null) {
final String sMimeType = m_aMimeType.getAsString();
// Check with request accept mime types
final QValue aQuality = m_aAcceptMimeTypeList.getQValueOfMimeType(m_aMimeType);
if (aQuality.isMinimumQuality()) {
final ICommonsOrderedMap<IMimeType, QValue> aBetterValues = m_aAcceptMimeTypeList.getAllQValuesGreaterThan(aQuality.getQuality());
logError("MimeType '" + sMimeType + "' is not at all supported by the request. Allowed values are: " + _getAsStringMimeTypes(aBetterValues));
} else if (aQuality.isLowValue()) {
// only in the debug version
if (GlobalDebug.isDebugMode()) {
// Inform if the quality of the request is <= 50%!
final ICommonsOrderedMap<IMimeType, QValue> aBetterValues = m_aAcceptMimeTypeList.getAllQValuesGreaterThan(aQuality.getQuality());
if (!aBetterValues.isEmpty())
logWarn("MimeType '" + sMimeType + "' is not best supported by the request (" + aQuality + "). Better MimeTypes are: " + _getAsStringMimeTypes(aBetterValues));
}
}
aHttpResponse.setContentType(sMimeType);
} else {
logWarn("No MimeType present");
}
// Charset
if (m_aCharset != null) {
final String sCharset = m_aCharset.name();
if (m_aMimeType == null)
logWarn("If no MimeType present, the client cannot get notified about the character encoding '" + sCharset + "'");
// Check with request charset
final QValue aQuality = m_aAcceptCharsetList.getQValueOfCharset(sCharset);
if (aQuality.isMinimumQuality()) {
final ICommonsOrderedMap<String, QValue> aBetterValues = m_aAcceptCharsetList.getAllQValuesGreaterThan(aQuality.getQuality());
logError("Character encoding '" + sCharset + "' is not at all supported by the request. Allowed values are: " + _getAsStringText(aBetterValues));
} else if (aQuality.isLowValue()) {
// Inform if the quality of the request is <= 50%!
final ICommonsOrderedMap<String, QValue> aBetterValues = m_aAcceptCharsetList.getAllQValuesGreaterThan(aQuality.getQuality());
if (!aBetterValues.isEmpty())
logWarn("Character encoding '" + sCharset + "' is not best supported by the request (" + aQuality + "). Better charsets are: " + _getAsStringText(aBetterValues));
}
aHttpResponse.setCharacterEncoding(sCharset);
} else if (m_aMimeType == null) {
logWarn("Also no character encoding present");
} else
switch(m_aMimeType.getContentType()) {
case TEXT:
case MULTIPART:
logWarn("A character encoding for MimeType '" + m_aMimeType.getAsString() + "' is appreciated.");
break;
default:
// Do we need character encoding here as well???
break;
}
// Add all cookies
if (m_aCookies != null)
for (final Cookie aCookie : m_aCookies.values()) aHttpResponse.addCookie(aCookie);
// Write the body to the response
_applyContent(aHttpResponse, bHasStatusCode);
}
Aggregations