blob: e859d72eed8e0a3197e2f26674f84e80b11acc69 [file] [log] [blame]
//
// ========================================================================
// Copyright (c) 1995-2015 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.client;
import java.net.CookieStore;
import java.net.HttpCookie;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jetty.client.api.Authentication;
import org.eclipse.jetty.client.api.Connection;
import org.eclipse.jetty.client.api.ContentProvider;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpVersion;
public abstract class HttpConnection implements Connection
{
private static final HttpField CHUNKED_FIELD = new HttpField(HttpHeader.TRANSFER_ENCODING, HttpHeaderValue.CHUNKED);
private final HttpDestination destination;
protected HttpConnection(HttpDestination destination)
{
this.destination = destination;
}
public HttpClient getHttpClient()
{
return destination.getHttpClient();
}
public HttpDestination getHttpDestination()
{
return destination;
}
@Override
public void send(Request request, Response.CompleteListener listener)
{
ArrayList<Response.ResponseListener> listeners = new ArrayList<>(2);
if (request.getTimeout() > 0)
{
TimeoutCompleteListener timeoutListener = new TimeoutCompleteListener(request);
timeoutListener.schedule(getHttpClient().getScheduler());
listeners.add(timeoutListener);
}
if (listener != null)
listeners.add(listener);
HttpExchange exchange = new HttpExchange(getHttpDestination(), (HttpRequest)request, listeners);
send(exchange);
}
protected abstract void send(HttpExchange exchange);
protected void normalizeRequest(Request request)
{
String method = request.getMethod();
HttpVersion version = request.getVersion();
HttpFields headers = request.getHeaders();
ContentProvider content = request.getContent();
ProxyConfiguration.Proxy proxy = destination.getProxy();
// Make sure the path is there
String path = request.getPath();
if (path.trim().length() == 0)
{
path = "/";
request.path(path);
}
if (proxy != null && !HttpMethod.CONNECT.is(method))
{
path = request.getURI().toString();
request.path(path);
}
// If we are HTTP 1.1, add the Host header
if (version.getVersion() > 10)
{
if (!headers.containsKey(HttpHeader.HOST.asString()))
headers.put(getHttpDestination().getHostField());
}
// Add content headers
if (content != null)
{
if (content instanceof ContentProvider.Typed)
{
if (!headers.containsKey(HttpHeader.CONTENT_TYPE.asString()))
{
String contentType = ((ContentProvider.Typed)content).getContentType();
if (contentType != null)
headers.put(HttpHeader.CONTENT_TYPE, contentType);
}
}
long contentLength = content.getLength();
if (contentLength >= 0)
{
if (!headers.containsKey(HttpHeader.CONTENT_LENGTH.asString()))
headers.put(HttpHeader.CONTENT_LENGTH, String.valueOf(contentLength));
}
else
{
if (!headers.containsKey(HttpHeader.TRANSFER_ENCODING.asString()))
headers.put(CHUNKED_FIELD);
}
}
// Cookies
CookieStore cookieStore = getHttpClient().getCookieStore();
if (cookieStore != null)
{
URI uri = request.getURI();
StringBuilder cookies = null;
if (uri != null)
cookies = convertCookies(cookieStore.get(uri), null);
cookies = convertCookies(request.getCookies(), cookies);
if (cookies != null)
request.header(HttpHeader.COOKIE.asString(), cookies.toString());
}
// Authorization
URI authenticationURI = proxy != null ? proxy.getURI() : request.getURI();
if (authenticationURI != null)
{
Authentication.Result authnResult = getHttpClient().getAuthenticationStore().findAuthenticationResult(authenticationURI);
if (authnResult != null)
authnResult.apply(request);
}
}
private StringBuilder convertCookies(List<HttpCookie> cookies, StringBuilder builder)
{
for (int i = 0; i < cookies.size(); ++i)
{
if (builder == null)
builder = new StringBuilder();
if (builder.length() > 0)
builder.append("; ");
HttpCookie cookie = cookies.get(i);
builder.append(cookie.getName()).append("=").append(cookie.getValue());
}
return builder;
}
@Override
public String toString()
{
return String.format("%s@%h", getClass().getSimpleName(), this);
}
}