Search in sources :

Example 1 with HttpHeader

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 &lt;=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;
}
Also used : HttpHeader(org.eclipse.jetty.http.HttpHeader) HostPortHttpField(org.eclipse.jetty.http.HostPortHttpField) HttpField(org.eclipse.jetty.http.HttpField) HttpSession(javax.servlet.http.HttpSession) HttpFields(org.eclipse.jetty.http.HttpFields)

Example 2 with HttpHeader

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);
}
Also used : HttpHeader(org.eclipse.jetty.http.HttpHeader) HostPortHttpField(org.eclipse.jetty.http.HostPortHttpField) HttpHeaderValue(org.eclipse.jetty.http.HttpHeaderValue)

Example 3 with HttpHeader

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;
}
Also used : HttpHeader(org.eclipse.jetty.http.HttpHeader) URI(java.net.URI)

Example 4 with HttpHeader

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);
}
Also used : Request(org.eclipse.jetty.server.Request) HttpServletRequest(javax.servlet.http.HttpServletRequest) ServletRequest(javax.servlet.ServletRequest) HttpURI(org.eclipse.jetty.http.HttpURI) ArrayDeque(java.util.ArrayDeque) HttpServletRequest(javax.servlet.http.HttpServletRequest) HttpHeader(org.eclipse.jetty.http.HttpHeader) HttpField(org.eclipse.jetty.http.HttpField) HttpFields(org.eclipse.jetty.http.HttpFields) PushBuilder(org.eclipse.jetty.server.PushBuilder)

Example 5 with HttpHeader

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;
}
Also used : HttpHeader(org.eclipse.jetty.http.HttpHeader) HttpField(org.eclipse.jetty.http.HttpField) Request(org.eclipse.jetty.client.api.Request)

Aggregations

HttpHeader (org.eclipse.jetty.http.HttpHeader)8 HttpField (org.eclipse.jetty.http.HttpField)5 HostPortHttpField (org.eclipse.jetty.http.HostPortHttpField)3 BadMessageException (org.eclipse.jetty.http.BadMessageException)2 HttpFields (org.eclipse.jetty.http.HttpFields)2 Entry (org.eclipse.jetty.http2.hpack.HpackContext.Entry)2 URI (java.net.URI)1 ArrayDeque (java.util.ArrayDeque)1 ServletRequest (javax.servlet.ServletRequest)1 HttpServletRequest (javax.servlet.http.HttpServletRequest)1 HttpSession (javax.servlet.http.HttpSession)1 Request (org.eclipse.jetty.client.api.Request)1 HttpHeaderValue (org.eclipse.jetty.http.HttpHeaderValue)1 HttpURI (org.eclipse.jetty.http.HttpURI)1 PreEncodedHttpField (org.eclipse.jetty.http.PreEncodedHttpField)1 StaticEntry (org.eclipse.jetty.http2.hpack.HpackContext.StaticEntry)1 PushBuilder (org.eclipse.jetty.server.PushBuilder)1 Request (org.eclipse.jetty.server.Request)1