use of org.eclipse.jetty.http.HttpHeader in project jetty.project by eclipse.
the class Request method getPushBuilder.
/* ------------------------------------------------------------ */
/** Get a PushBuilder associated with this request initialized as follows:<ul>
* <li>The method is initialized to "GET"</li>
* <li>The headers from this request are copied to the Builder, except for:<ul>
* <li>Conditional headers (eg. If-Modified-Since)
* <li>Range headers
* <li>Expect headers
* <li>Authorization headers
* <li>Referrer headers
* </ul></li>
* <li>If the request was Authenticated, an Authorization header will
* be set with a container generated token that will result in equivalent
* Authorization</li>
* <li>The query string from {@link #getQueryString()}
* <li>The {@link #getRequestedSessionId()} value, unless at the time
* of the call {@link #getSession(boolean)}
* has previously been called to create a new {@link HttpSession}, in
* which case the new session ID will be used as the PushBuilders
* requested session ID.</li>
* <li>The source of the requested session id will be the same as for
* this request</li>
* <li>The builders Referer header will be set to {@link #getRequestURL()}
* plus any {@link #getQueryString()} </li>
* <li>If {@link HttpServletResponse#addCookie(Cookie)} has been called
* on the associated response, then a corresponding Cookie header will be added
* to the PushBuilder, unless the {@link Cookie#getMaxAge()} is <=0, in which
* case the Cookie will be removed from the builder.</li>
* <li>If this request has has the conditional headers If-Modified-Since or
* If-None-Match then the {@link PushBuilderImpl#isConditional()} header is set
* to true.
* </ul>
*
* <p>Each call to getPushBuilder() will return a new instance
* of a PushBuilder based off this Request. Any mutations to the
* returned PushBuilder are not reflected on future returns.
* @return A new PushBuilder or null if push is not supported
*/
public PushBuilder getPushBuilder() {
if (!isPushSupported())
throw new IllegalStateException(String.format("%s,push=%b,channel=%s", this, isPush(), getHttpChannel()));
HttpFields fields = new HttpFields(getHttpFields().size() + 5);
boolean conditional = false;
for (HttpField field : getHttpFields()) {
HttpHeader header = field.getHeader();
if (header == null)
fields.add(field);
else {
switch(header) {
case IF_MATCH:
case IF_RANGE:
case IF_UNMODIFIED_SINCE:
case RANGE:
case EXPECT:
case REFERER:
case COOKIE:
continue;
case AUTHORIZATION:
continue;
case IF_NONE_MATCH:
case IF_MODIFIED_SINCE:
conditional = true;
continue;
default:
fields.add(field);
}
}
}
String id = null;
try {
HttpSession session = getSession();
if (session != null) {
// checks if session is valid
session.getLastAccessedTime();
id = session.getId();
} else
id = getRequestedSessionId();
} catch (IllegalStateException e) {
id = getRequestedSessionId();
}
PushBuilder builder = new PushBuilderImpl(this, fields, getMethod(), getQueryString(), id, conditional);
builder.addHeader("referer", getRequestURL().toString());
return builder;
}
use of org.eclipse.jetty.http.HttpHeader in project jetty.project by eclipse.
the class HttpChannelOverHttp method parsedHeader.
@Override
public void parsedHeader(HttpField field) {
HttpHeader header = field.getHeader();
String value = field.getValue();
if (header != null) {
switch(header) {
case CONNECTION:
_connection = field;
break;
case HOST:
if (!_metadata.getURI().isAbsolute() && field instanceof HostPortHttpField) {
HostPortHttpField hp = (HostPortHttpField) field;
_metadata.getURI().setAuthority(hp.getHost(), hp.getPort());
}
break;
case EXPECT:
{
if (_metadata.getHttpVersion() == HttpVersion.HTTP_1_1) {
HttpHeaderValue expect = HttpHeaderValue.CACHE.get(value);
switch(expect == null ? HttpHeaderValue.UNKNOWN : expect) {
case CONTINUE:
_expect100Continue = true;
break;
case PROCESSING:
_expect102Processing = true;
break;
default:
String[] values = field.getValues();
for (int i = 0; values != null && i < values.length; i++) {
expect = HttpHeaderValue.CACHE.get(values[i].trim());
if (expect == null)
_unknownExpectation = true;
else {
switch(expect) {
case CONTINUE:
_expect100Continue = true;
break;
case PROCESSING:
_expect102Processing = true;
break;
default:
_unknownExpectation = true;
}
}
}
}
}
break;
}
case UPGRADE:
_upgrade = field;
break;
default:
break;
}
}
_fields.add(field);
}
use of org.eclipse.jetty.http.HttpHeader in project jetty.project by eclipse.
the class HttpReceiver method responseHeader.
/**
* Method to be invoked when a response HTTP header is available.
* <p>
* Subclasses must not have added the header to the {@link Response} object of the {@link HttpExchange}
* prior invoking this method.
* <p>
* This method takes case of notifying {@link org.eclipse.jetty.client.api.Response.HeaderListener}s and storing cookies.
*
* @param exchange the HTTP exchange
* @param field the response HTTP field
* @return whether the processing should continue
*/
protected boolean responseHeader(HttpExchange exchange, HttpField field) {
out: while (true) {
ResponseState current = responseState.get();
switch(current) {
case BEGIN:
case HEADER:
{
if (updateResponseState(current, ResponseState.TRANSIENT))
break out;
break;
}
default:
{
return false;
}
}
}
HttpResponse response = exchange.getResponse();
ResponseNotifier notifier = getHttpDestination().getResponseNotifier();
boolean process = notifier.notifyHeader(exchange.getConversation().getResponseListeners(), response, field);
if (process) {
response.getHeaders().add(field);
HttpHeader fieldHeader = field.getHeader();
if (fieldHeader != null) {
switch(fieldHeader) {
case SET_COOKIE:
case SET_COOKIE2:
{
URI uri = exchange.getRequest().getURI();
if (uri != null)
storeCookie(uri, field);
break;
}
default:
{
break;
}
}
}
}
if (updateResponseState(ResponseState.TRANSIENT, ResponseState.HEADER))
return true;
terminateResponse(exchange);
return false;
}
use of org.eclipse.jetty.http.HttpHeader in project jetty.project by eclipse.
the class PushCacheFilter method doFilter.
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
Request jettyRequest = Request.getBaseRequest(request);
if (HttpVersion.fromString(request.getProtocol()).getVersion() < 20 || !HttpMethod.GET.is(request.getMethod()) || !jettyRequest.isPushSupported()) {
chain.doFilter(req, resp);
return;
}
long now = System.nanoTime();
// Iterating over fields is more efficient than multiple gets
HttpFields fields = jettyRequest.getHttpFields();
boolean conditional = false;
String referrer = null;
loop: for (int i = 0; i < fields.size(); i++) {
HttpField field = fields.getField(i);
HttpHeader header = field.getHeader();
if (header == null)
continue;
switch(header) {
case IF_MATCH:
case IF_MODIFIED_SINCE:
case IF_NONE_MATCH:
case IF_UNMODIFIED_SINCE:
conditional = true;
break loop;
case REFERER:
referrer = field.getValue();
break;
default:
break;
}
}
if (LOG.isDebugEnabled())
LOG.debug("{} {} referrer={} conditional={}", request.getMethod(), request.getRequestURI(), referrer, conditional);
String path = request.getRequestURI();
String query = request.getQueryString();
if (_useQueryInKey && query != null)
path += "?" + query;
if (referrer != null) {
HttpURI referrerURI = new HttpURI(referrer);
String host = referrerURI.getHost();
int port = referrerURI.getPort();
if (port <= 0)
port = request.isSecure() ? 443 : 80;
boolean referredFromHere = _hosts.size() > 0 ? _hosts.contains(host) : host.equals(request.getServerName());
referredFromHere &= _ports.size() > 0 ? _ports.contains(port) : port == request.getServerPort();
if (referredFromHere) {
if (HttpMethod.GET.is(request.getMethod())) {
String referrerPath = _useQueryInKey ? referrerURI.getPathQuery() : referrerURI.getPath();
if (referrerPath == null)
referrerPath = "/";
if (referrerPath.startsWith(request.getContextPath() + "/")) {
if (!referrerPath.equals(path)) {
PrimaryResource primaryResource = _cache.get(referrerPath);
if (primaryResource != null) {
long primaryTimestamp = primaryResource._timestamp.get();
if (primaryTimestamp != 0) {
if (now - primaryTimestamp < TimeUnit.MILLISECONDS.toNanos(_associatePeriod)) {
Set<String> associated = primaryResource._associated;
// Not strictly concurrent-safe, just best effort to limit associations.
if (associated.size() <= _maxAssociations) {
if (associated.add(path)) {
if (LOG.isDebugEnabled())
LOG.debug("Associated {} to {}", path, referrerPath);
}
} else {
if (LOG.isDebugEnabled())
LOG.debug("Not associated {} to {}, exceeded max associations of {}", path, referrerPath, _maxAssociations);
}
} else {
if (LOG.isDebugEnabled())
LOG.debug("Not associated {} to {}, outside associate period of {}ms", path, referrerPath, _associatePeriod);
}
}
}
} else {
if (LOG.isDebugEnabled())
LOG.debug("Not associated {} to {}, referring to self", path, referrerPath);
}
} else {
if (LOG.isDebugEnabled())
LOG.debug("Not associated {} to {}, different context", path, referrerPath);
}
}
} else {
if (LOG.isDebugEnabled())
LOG.debug("External referrer {}", referrer);
}
}
PrimaryResource primaryResource = _cache.get(path);
if (primaryResource == null) {
PrimaryResource r = new PrimaryResource();
primaryResource = _cache.putIfAbsent(path, r);
primaryResource = primaryResource == null ? r : primaryResource;
primaryResource._timestamp.compareAndSet(0, now);
if (LOG.isDebugEnabled())
LOG.debug("Cached primary resource {}", path);
} else {
long last = primaryResource._timestamp.get();
if (last < _renew && primaryResource._timestamp.compareAndSet(last, now)) {
primaryResource._associated.clear();
if (LOG.isDebugEnabled())
LOG.debug("Clear associated resources for {}", path);
}
}
// Push associated resources.
if (!conditional && !primaryResource._associated.isEmpty()) {
PushBuilder pushBuilder = jettyRequest.getPushBuilder();
// Breadth-first push of associated resources.
Queue<PrimaryResource> queue = new ArrayDeque<>();
queue.offer(primaryResource);
while (!queue.isEmpty()) {
PrimaryResource parent = queue.poll();
for (String childPath : parent._associated) {
PrimaryResource child = _cache.get(childPath);
if (child != null)
queue.offer(child);
if (LOG.isDebugEnabled())
LOG.debug("Pushing {} for {}", childPath, path);
pushBuilder.path(childPath).push();
}
}
}
chain.doFilter(request, resp);
}
use of org.eclipse.jetty.http.HttpHeader in project jetty.project by eclipse.
the class HttpClient method copyRequest.
protected Request copyRequest(HttpRequest oldRequest, URI newURI) {
Request newRequest = newHttpRequest(oldRequest.getConversation(), newURI);
newRequest.method(oldRequest.getMethod()).version(oldRequest.getVersion()).content(oldRequest.getContent()).idleTimeout(oldRequest.getIdleTimeout(), TimeUnit.MILLISECONDS).timeout(oldRequest.getTimeout(), TimeUnit.MILLISECONDS).followRedirects(oldRequest.isFollowRedirects());
for (HttpField field : oldRequest.getHeaders()) {
HttpHeader header = field.getHeader();
// We have a new URI, so skip the host header if present.
if (HttpHeader.HOST == header)
continue;
// Remove expectation headers.
if (HttpHeader.EXPECT == header)
continue;
// Remove cookies.
if (HttpHeader.COOKIE == header)
continue;
// Remove authorization headers.
if (HttpHeader.AUTHORIZATION == header || HttpHeader.PROXY_AUTHORIZATION == header)
continue;
String name = field.getName();
String value = field.getValue();
if (!newRequest.getHeaders().contains(name, value))
newRequest.header(name, value);
}
return newRequest;
}
Aggregations