/**
* Copyright 2005-2014 Restlet
*
* The contents of this file are subject to the terms of one of the following
* open source licenses: Apache 2.0 or or EPL 1.0 (the "Licenses"). You can
* select the license that you prefer but you may not use this file except in
* compliance with one of these Licenses.
*
* You can obtain a copy of the Apache 2.0 license at
* http://www.opensource.org/licenses/apache-2.0
*
* You can obtain a copy of the EPL 1.0 license at
* http://www.opensource.org/licenses/eclipse-1.0
*
* See the Licenses for the specific language governing permissions and
* limitations under the Licenses.
*
* Alternatively, you can obtain a royalty free commercial license with less
* limitations, transferable or non-transferable, directly at
* http://restlet.com/products/restlet-framework
*
* Restlet is a registered trademark of Restlet S.A.S.
*/
package org.restlet.engine.adapter;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Level;
import org.restlet.Context;
import org.restlet.Server;
import org.restlet.engine.Engine;
import org.restlet.engine.connector.ServerHelper;
/**
* Base HTTP server connector. Here is the list of parameters that are
* supported. They should be set in the Server's context before it is started:
* <table>
* <tr>
* <th>Parameter name</th>
* <th>Value type</th>
* <th>Default value</th>
* <th>Description</th>
* </tr>
* <tr>
* <td>useForwardedForHeader</td>
* <td>boolean</td>
* <td>false</td>
* <td>Lookup the "X-Forwarded-For" header supported by popular proxies and
* caches and uses it to populate the Request.getClientAddresses() method
* result. This information is only safe for intermediary components within your
* local network. Other addresses could easily be changed by setting a fake
* header and should not be trusted for serious security checks.</td>
* </tr>
* <tr>
* <td>adapter</td>
* <td>String</td>
* <td>org.restlet.engine.adapter.ServerAdapter</td>
* <td>Class name of the adapter of low-level HTTP calls into high level
* requests and responses.</td>
* </tr>
* </table>
*
* @author Jerome Louvel
*/
public class HttpServerHelper extends ServerHelper {
/** The adapter from HTTP calls to uniform calls. */
private volatile ServerAdapter adapter;
/**
* Default constructor. Note that many methods assume that a non-null server
* is set to work properly. You can use the setHelped(Server) method for
* this purpose or better rely on the other constructor.
*/
public HttpServerHelper() {
this(null);
}
/**
* Constructor.
*
* @param server
* The server to help.
*/
public HttpServerHelper(Server server) {
super(server);
this.adapter = null;
}
/**
* Returns the adapter from HTTP calls to uniform calls.
*
* @return the adapter from HTTP calls to uniform calls.
*/
public ServerAdapter getAdapter() {
if (this.adapter == null) {
try {
final String adapterClass = getHelpedParameters()
.getFirstValue("adapter",
"org.restlet.engine.adapter.ServerAdapter");
this.adapter = (ServerAdapter) Engine.loadClass(adapterClass)
.getConstructor(Context.class)
.newInstance(getContext());
} catch (IllegalArgumentException e) {
getLogger().log(Level.SEVERE,
"Unable to create the HTTP server adapter", e);
} catch (SecurityException e) {
getLogger().log(Level.SEVERE,
"Unable to create the HTTP server adapter", e);
} catch (InstantiationException e) {
getLogger().log(Level.SEVERE,
"Unable to create the HTTP server adapter", e);
} catch (IllegalAccessException e) {
getLogger().log(Level.SEVERE,
"Unable to create the HTTP server adapter", e);
} catch (InvocationTargetException e) {
getLogger().log(Level.SEVERE,
"Unable to create the HTTP server adapter", e);
} catch (NoSuchMethodException e) {
getLogger().log(Level.SEVERE,
"Unable to create the HTTP server adapter", e);
} catch (ClassNotFoundException e) {
getLogger().log(Level.SEVERE,
"Unable to create the HTTP server adapter", e);
}
}
return this.adapter;
}
/**
* Handles the connector call. The default behavior is to create an REST
* call and delegate it to the attached Restlet.
*
* @param httpCall
* The HTTP server call.
*/
public void handle(ServerCall httpCall) {
try {
HttpRequest request = getAdapter().toRequest(httpCall);
HttpResponse response = new HttpResponse(httpCall, request);
handle(request, response);
getAdapter().commit(response);
} catch (Exception e) {
getLogger().log(Level.WARNING,
"Error while handling an HTTP server call", e);
} finally {
Engine.clearThreadLocalVariables();
}
}
/**
* Sets the adapter from HTTP calls to uniform calls.
*
* @param adapter
* The converter to set.
*/
public void setAdapter(ServerAdapter adapter) {
this.adapter = adapter;
}
}