Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Why Restlet is not allowing to set response headers? #1464

Unanswered
kerbymart asked this question in Q&A
Discussion options

This code:

public class HttpHeadersManager {
 private static final int DAY_IN_MINUTES = 3600;
 private final Series<Header> requestHeaders;
 private final Series<Header> responseHeaders;
 public HttpHeadersManager(Series<Header> requestHeaders, Series<Header> responseHeaders) {
 this.requestHeaders = requestHeaders;
 this.responseHeaders = responseHeaders;
 }
 public String getHeaderValue(Series<Header> headers, String name) {
 return headers.getFirst(name) != null ? headers.getFirst(name).getValue() : "";
 }
 public String getAcceptEncoding() {
 return getHeaderValue(requestHeaders, "Accept-Encoding");
 }
 public boolean canAcceptGzip() {
 return getAcceptEncoding().contains("gzip");
 }
 public void setCacheHeaders(String path) {
 if (isNoCache(path)) {
 setNoCacheHeaders();
 } else if (isCache(path)) {
 setCacheHeaders();
 }
 }
 public void setEncodingHeaders() {
 responseHeaders.set("Transfer-Encoding", "chunked");
 }
 private boolean isNoCache(String path) {
 return path.contains(".nocache.");
 }
 private void setNoCacheHeaders() {
 Date now = new Date();
 responseHeaders.set("Date", String.valueOf(now.getTime()));
 responseHeaders.set("Last-Modified", String.valueOf(now.getTime()));
 responseHeaders.set("Expires", "0");
 responseHeaders.set("Pragma", "no-cache");
 responseHeaders.set("Cache-control", "no-cache, must-revalidate, pre-check=0, post-check=0");
 }
 private boolean isCache(String path) {
 return path.contains(".cache.");
 }
 private void setCacheHeaders() {
 final Calendar calendar = Calendar.getInstance();
 calendar.setTime(new Date());
 calendar.add(Calendar.HOUR, 24);
 responseHeaders.set("Expires", String.valueOf(calendar.getTime().getTime()));
 responseHeaders.set("Cache-control", "max-age=" + DAY_IN_MINUTES + ", public, immutable");
 responseHeaders.set("Pragma", "");
 }
}

Is throwing this "error"


Addition of the standard header "Transfer-Encoding" is discouraged as a future version of the Restlet API will directly support it.
Addition of the standard header "Date" is not allowed. Please use the equivalent property in the Restlet API.
Addition of the standard header "Last-Modified" is not allowed. Please use the equivalent property in the Restlet API.
Addition of the standard header "Expires" is not allowed. Please use the equivalent property in the Restlet API.
Addition of the standard header "Pragma" is discouraged as a future version of the Restlet API will directly support it.
Addition of the standard header "Cache-control" is not allowed. Please use the equivalent property in the Restlet API.

Is there a workaround?

You must be logged in to vote

Replies: 3 comments 3 replies

Comment options

@jlouvel and @thboileau

Would you agree that this should not be enforced?

// org.restlet.engine.header.HeaderUtils.java

	/**
	 * Adds extension headers if they are non-standard headers.
	 * 
	 * @param existingHeaders The headers to update.
	 * @param additionalHeaders The headers to add.
	 */
	public static void addExtensionHeaders(Series<Header> existingHeaders, Series<Header> additionalHeaders) {
		if (additionalHeaders != null) {
			for (Header param : additionalHeaders) {
				if (STANDARD_HEADERS.contains(param.getName())) {
					// Standard headers that can't be overridden
					Context.getCurrentLogger().warning("Addition of the standard header \"" + param.getName()
							+ "\" is not allowed. Please use the equivalent property in the Restlet API.");
				} else if (UNSUPPORTED_STANDARD_HEADERS.contains(param.getName())) {
					Context.getCurrentLogger().warning("Addition of the standard header \"" + param.getName()
							+ "\" is discouraged as a future version of the Restlet API will directly support it.");
					existingHeaders.add(param);
				} else {
					existingHeaders.add(param);
				}
			}
		}
	}

Or at least a way to override this. For example in our case that we are building a static site server with Restlet then this rule is not allowing a core function.

You must be logged in to vote
3 replies
Comment options

I'm trying to hack it with

public class RestletHeaderTweaks {
 @SuppressWarnings({"unchecked","rawtypes"})
 public static void allowStandardHeader(String headerName) {
 try {
 Field f = org.restlet.engine.header.HeaderUtils.class
 .getDeclaredField("STANDARD_HEADERS");
 f.setAccessible(true);
 

However, newer JVMs do not allow this kind of reflection.

Comment options

and btw, the HttpHeadersManager in my example is just for illustration, our server have a function to allow end-users to modify HTTP response headers.

Comment options

Hi @kerbymart The main purpose of Restlet API is to abstract the HTTP headers into proper Java objects, hence we forbid the manual setting of standard headers other we wouldn't know when to override them or not.

This page has a mapping tables of those headers to the corresponding Java objects:
https://restlet.talend.com/documentation/user-guide/2.5/core/http-headers-mapping/

Could you explain your use case a bit more and why you can't set those headers via the proper Restlet API objects?

If you are not yet familiar with this tutorial, I encourage you to review it:
https://restlet.talend.com/documentation/tutorials/2.5/overview/

Comment options

Yes, it's possible to set the headers via the standard API, but our use-case is different, as mentioned it's a web hosting platform. And websites have _headers file like this:

Header-Name: Header Value

Which the platform does not forbid any value, so if it relies on the "standard" API then it could be filtered.

You must be logged in to vote
0 replies
Comment options

I'm still not 100% clear about the use case. Serving static files with Restlet is possible for example using the Directory class.

If the goal is to allow custom setting of response headers on static files returned by Restlet, then you would need to override the ServerAdapter#addResponseHeaders(HttpResponse) method. To set a custom adapter, you need to call HttpServerHelper#setAdapter

Hope this helps!

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /