| // |
| // ======================================================================== |
| // Copyright (c) 1995-2017 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.client.http; |
| |
| import java.net.URI; |
| import java.util.Locale; |
| |
| import org.eclipse.jetty.client.HttpChannel; |
| import org.eclipse.jetty.client.HttpContent; |
| import org.eclipse.jetty.client.HttpExchange; |
| import org.eclipse.jetty.client.HttpSender; |
| import org.eclipse.jetty.client.api.Request; |
| import org.eclipse.jetty.fcgi.FCGI; |
| import org.eclipse.jetty.fcgi.generator.ClientGenerator; |
| import org.eclipse.jetty.fcgi.generator.Generator; |
| import org.eclipse.jetty.http.HttpField; |
| import org.eclipse.jetty.http.HttpFields; |
| import org.eclipse.jetty.http.HttpHeader; |
| import org.eclipse.jetty.util.BufferUtil; |
| import org.eclipse.jetty.util.Callback; |
| import org.eclipse.jetty.util.Jetty; |
| |
| public class HttpSenderOverFCGI extends HttpSender |
| { |
| private final ClientGenerator generator; |
| |
| public HttpSenderOverFCGI(HttpChannel channel) |
| { |
| super(channel); |
| this.generator = new ClientGenerator(channel.getHttpDestination().getHttpClient().getByteBufferPool()); |
| } |
| |
| @Override |
| protected HttpChannelOverFCGI getHttpChannel() |
| { |
| return (HttpChannelOverFCGI)super.getHttpChannel(); |
| } |
| |
| @Override |
| protected void sendHeaders(HttpExchange exchange, HttpContent content, Callback callback) |
| { |
| Request request = exchange.getRequest(); |
| // Copy the request headers to be able to convert them properly |
| HttpFields headers = new HttpFields(); |
| for (HttpField field : request.getHeaders()) |
| headers.put(field); |
| HttpFields fcgiHeaders = new HttpFields(); |
| |
| // FastCGI headers based on the URI |
| URI uri = request.getURI(); |
| String path = uri == null ? request.getPath() : uri.getRawPath(); |
| fcgiHeaders.put(FCGI.Headers.DOCUMENT_URI, path); |
| String query = uri == null ? null : uri.getRawQuery(); |
| fcgiHeaders.put(FCGI.Headers.QUERY_STRING, query == null ? "" : query); |
| |
| // FastCGI headers based on HTTP headers |
| HttpField httpField = headers.remove(HttpHeader.AUTHORIZATION); |
| if (httpField != null) |
| fcgiHeaders.put(FCGI.Headers.AUTH_TYPE, httpField.getValue()); |
| httpField = headers.remove(HttpHeader.CONTENT_LENGTH); |
| fcgiHeaders.put(FCGI.Headers.CONTENT_LENGTH, httpField == null ? "" : httpField.getValue()); |
| httpField = headers.remove(HttpHeader.CONTENT_TYPE); |
| fcgiHeaders.put(FCGI.Headers.CONTENT_TYPE, httpField == null ? "" : httpField.getValue()); |
| |
| // FastCGI headers that are not based on HTTP headers nor URI |
| fcgiHeaders.put(FCGI.Headers.REQUEST_METHOD, request.getMethod()); |
| fcgiHeaders.put(FCGI.Headers.SERVER_PROTOCOL, request.getVersion().asString()); |
| fcgiHeaders.put(FCGI.Headers.GATEWAY_INTERFACE, "CGI/1.1"); |
| fcgiHeaders.put(FCGI.Headers.SERVER_SOFTWARE, "Jetty/" + Jetty.VERSION); |
| |
| // Translate remaining HTTP header into the HTTP_* format |
| for (HttpField field : headers) |
| { |
| String name = field.getName(); |
| String fcgiName = "HTTP_" + name.replaceAll("-", "_").toUpperCase(Locale.ENGLISH); |
| fcgiHeaders.add(fcgiName, field.getValue()); |
| } |
| |
| // Give a chance to the transport implementation to customize the FastCGI headers |
| HttpClientTransportOverFCGI transport = (HttpClientTransportOverFCGI)getHttpChannel().getHttpDestination().getHttpClient().getTransport(); |
| transport.customize(request, fcgiHeaders); |
| |
| int id = getHttpChannel().getRequest(); |
| boolean hasContent = content.hasContent(); |
| Generator.Result headersResult = generator.generateRequestHeaders(id, fcgiHeaders, |
| hasContent ? callback : Callback.NOOP); |
| if (hasContent) |
| { |
| getHttpChannel().flush(headersResult); |
| } |
| else |
| { |
| Generator.Result noContentResult = generator.generateRequestContent(id, BufferUtil.EMPTY_BUFFER, true, callback); |
| getHttpChannel().flush(headersResult, noContentResult); |
| } |
| } |
| |
| @Override |
| protected void sendContent(HttpExchange exchange, HttpContent content, Callback callback) |
| { |
| if (content.isConsumed()) |
| { |
| callback.succeeded(); |
| } |
| else |
| { |
| int request = getHttpChannel().getRequest(); |
| Generator.Result result = generator.generateRequestContent(request, content.getByteBuffer(), content.isLast(), callback); |
| getHttpChannel().flush(result); |
| } |
| } |
| } |