blob: 5856081540b55832a828f0f24a095f6a9e2c2194 [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.fcgi.server;
import java.nio.ByteBuffer;
import org.eclipse.jetty.fcgi.generator.Flusher;
import org.eclipse.jetty.fcgi.generator.Generator;
import org.eclipse.jetty.fcgi.generator.ServerGenerator;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.server.HttpTransport;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
public class HttpTransportOverFCGI implements HttpTransport
{
private final ServerGenerator generator;
private final Flusher flusher;
private final int request;
private volatile boolean head;
private volatile boolean shutdown;
private volatile boolean aborted;
public HttpTransportOverFCGI(ByteBufferPool byteBufferPool, Flusher flusher, int request, boolean sendStatus200)
{
this.generator = new ServerGenerator(byteBufferPool, sendStatus200);
this.flusher = flusher;
this.request = request;
}
@Override
public boolean isOptimizedForDirectBuffers()
{
return false;
}
@Override
public void send(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback)
{
if (info!=null)
commit(info,head,content,lastContent,callback);
else
{
if (head)
{
if (lastContent)
{
Generator.Result result = generateResponseContent(BufferUtil.EMPTY_BUFFER, true, callback);
flusher.flush(result);
}
else
{
// Skip content generation
callback.succeeded();
}
}
else
{
Generator.Result result = generateResponseContent(content, lastContent, callback);
flusher.flush(result);
}
if (lastContent && shutdown)
flusher.shutdown();
}
}
@Override
public boolean isPushSupported()
{
return false;
}
@Override
public void push(org.eclipse.jetty.http.MetaData.Request request)
{
// LOG.debug("ignore push in {}",this);
}
private void commit(MetaData.Response info, boolean head, ByteBuffer content, boolean lastContent, Callback callback)
{
this.head = head;
boolean shutdown = this.shutdown = info.getFields().contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString());
if (head)
{
if (lastContent)
{
Generator.Result headersResult = generateResponseHeaders(info, Callback.NOOP);
Generator.Result contentResult = generateResponseContent(BufferUtil.EMPTY_BUFFER, true, callback);
flusher.flush(headersResult, contentResult);
}
else
{
Generator.Result headersResult = generateResponseHeaders(info, callback);
flusher.flush(headersResult);
}
}
else
{
Generator.Result headersResult = generateResponseHeaders(info, Callback.NOOP);
Generator.Result contentResult = generateResponseContent(content, lastContent, callback);
flusher.flush(headersResult, contentResult);
}
if (lastContent && shutdown)
flusher.shutdown();
}
protected Generator.Result generateResponseHeaders(MetaData.Response info, Callback callback)
{
return generator.generateResponseHeaders(request, info.getStatus(), info.getReason(), info.getFields(), callback);
}
protected Generator.Result generateResponseContent(ByteBuffer buffer, boolean lastContent, Callback callback)
{
return generator.generateResponseContent(request, buffer, lastContent, aborted, callback);
}
@Override
public void abort(Throwable failure)
{
aborted = true;
}
@Override
public void onCompleted()
{
}
}