/**
* 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.connector;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import org.restlet.Server;
import org.restlet.data.Header;
import org.restlet.engine.adapter.ServerCall;
import org.restlet.representation.Representation;
import org.restlet.util.Series;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
/**
* Call that is used by the Basic HTTP server.
*
* @author Jerome Louvel
*/
public class HttpExchangeCall extends ServerCall {
/** The wrapped HTTP exchange. */
private final HttpExchange exchange;
/** Indicates if the request headers were parsed and added. */
private volatile boolean requestHeadersAdded;
/**
* Constructor.
*
* @param server
* @param exchange
*/
public HttpExchangeCall(Server server, HttpExchange exchange) {
this(server, exchange, false);
}
/**
* Constructor.
*
* @param server
* @param exchange
* @param confidential
*/
public HttpExchangeCall(Server server, HttpExchange exchange,
boolean confidential) {
super(server);
this.exchange = exchange;
setConfidential(confidential);
}
@Override
public boolean abort() {
this.exchange.close();
return true;
}
@Override
public void flushBuffers() throws IOException {
this.exchange.getResponseBody().flush();
}
@Override
public String getClientAddress() {
return this.exchange.getRemoteAddress().getAddress().getHostAddress();
}
@Override
public int getClientPort() {
return this.exchange.getRemoteAddress().getPort();
}
@Override
public String getMethod() {
return this.exchange.getRequestMethod();
}
@Override
public Series<Header> getRequestHeaders() {
final Series<Header> result = super.getRequestHeaders();
if (!this.requestHeadersAdded) {
final Headers headers = this.exchange.getRequestHeaders();
for (String name : headers.keySet()) {
for (String value : (List<String>) headers.get(name)) {
result.add(name, value);
}
}
this.requestHeadersAdded = true;
}
return result;
}
@Override
public InputStream getRequestEntityStream(long size) {
return this.exchange.getRequestBody();
}
@Override
public InputStream getRequestHeadStream() {
return null;
}
@Override
public String getRequestUri() {
return this.exchange.getRequestURI().toString();
}
@Override
public OutputStream getResponseEntityStream() {
return this.exchange.getResponseBody();
}
@Override
public void writeResponseHead(org.restlet.Response restletResponse)
throws IOException {
final Headers headers = this.exchange.getResponseHeaders();
for (Header header : getResponseHeaders()) {
headers.add(header.getName(), header.getValue());
}
// Send the headers
Representation entity = restletResponse.getEntity();
long responseLength = 0;
if (entity == null || !entity.isAvailable()) {
responseLength = -1;
} else if (entity.getAvailableSize() != Representation.UNKNOWN_SIZE) {
responseLength = entity.getAvailableSize();
}
this.exchange.sendResponseHeaders(getStatusCode(), responseLength);
}
}