org.pac4j.vertx.VertxWebContext.java Source code

Java tutorial

Introduction

Here is the source code for org.pac4j.vertx.VertxWebContext.java

Source

/*
  Copyright 2014 - 2015 pac4j organization
    
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
    
   http://www.apache.org/licenses/LICENSE-2.0
    
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
package org.pac4j.vertx;

import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.Session;
import org.pac4j.core.context.BaseResponseContext;
import org.pac4j.core.context.Cookie;
import org.pac4j.core.context.HttpConstants;
import org.pac4j.vertx.auth.Pac4jUser;
import org.pac4j.vertx.core.DefaultJsonConverter;

import java.net.URI;
import java.net.URISyntaxException;
import java.security.InvalidParameterException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * WebContext implementation for Vert.x 3.
 *
 * @author Jeremy Prime
 * @since 2.0.0
 */
public class VertxWebContext extends BaseResponseContext {

    private final RoutingContext routingContext;
    private final String method;
    private final String serverName;
    private final int serverPort;
    private final String fullUrl;
    private final String scheme;
    private final String remoteAddress;
    private final JsonObject headers;
    private final JsonObject parameters;
    private final Map<String, String[]> mapParameters;

    private boolean contentHasBeenWritten = false; // Need to set chunked before first write of any content

    public VertxWebContext(final RoutingContext routingContext) {
        final HttpServerRequest request = routingContext.request();
        this.routingContext = routingContext;
        this.method = request.method().toString();

        this.fullUrl = request.absoluteURI();
        URI uri;
        try {
            uri = new URI(fullUrl);
        } catch (URISyntaxException e) {
            e.printStackTrace();
            throw new InvalidParameterException(
                    "Request to invalid URL " + fullUrl + " while constructing VertxWebContext");
        }
        this.scheme = uri.getScheme();
        this.serverName = uri.getHost();
        this.serverPort = (uri.getPort() != -1) ? uri.getPort() : scheme.equals("http") ? 80 : 443;
        this.remoteAddress = request.remoteAddress().toString();

        headers = new JsonObject();
        for (String name : request.headers().names()) {
            headers.put(name, request.headers().get(name));
        }

        parameters = new JsonObject();
        for (String name : request.params().names()) {
            parameters.put(name, new JsonArray(Arrays.asList(request.params().getAll(name).toArray())));
        }

        mapParameters = new HashMap<>();
        for (String name : parameters.fieldNames()) {
            JsonArray params = parameters.getJsonArray(name);
            String[] values = new String[params.size()];
            int i = 0;
            for (Object o : params) {
                values[i++] = (String) o;
            }
            mapParameters.put(name, values);
        }

    }

    public void failResponse(final int status) {
        routingContext.fail(status);
    }

    public void completeResponse() {
        routingContext.response().end();
    }

    @Override
    public String getRequestParameter(String name) {
        JsonArray values = parameters.getJsonArray(name);
        if (values != null && values.size() > 0) {
            return values.getString(0);
        }
        return null;
    }

    @Override
    public Map<String, String[]> getRequestParameters() {
        return mapParameters;
    }

    @Override
    public Object getRequestAttribute(String s) {
        return routingContext.get(s);
    }

    @Override
    public void setRequestAttribute(String s, Object o) {
        routingContext.put(s, o);
    }

    @Override
    public String getRequestHeader(String name) {
        return headers.getString(name);
    }

    @Override
    public void setSessionAttribute(String name, Object value) {
        Session session = routingContext.session();
        if (session == null) {
            throw new IllegalStateException("Session required for use of getSessionAttribute");
        }
        // Need to convert to something that can be passed round a distributed vert.x session cleanly
        if (value == null) {
            session.remove(name);
        } else {
            session.put(name, DefaultJsonConverter.getInstance().encodeObject(value));
        }
    }

    @Override
    public Object getSessionAttribute(String name) {
        Session session = routingContext.session();
        if (session == null) {
            throw new IllegalStateException("Session required for use of getSessionAttribute");
        }
        return DefaultJsonConverter.getInstance().decodeObject(session.get(name));
    }

    @Override
    public Object getSessionIdentifier() {
        return routingContext.session().id();
    }

    @Override
    public String getRequestMethod() {
        return method;
    }

    @Override
    public String getRemoteAddr() {
        return remoteAddress;
    }

    @Override
    public void writeResponseContent(String content) {
        if (!contentHasBeenWritten) {
            routingContext.response().setChunked(true);
            contentHasBeenWritten = true;
        }
        routingContext.response().write(content);
    }

    @Override
    public void setResponseStatus(int code) {
        routingContext.response().setStatusCode(code);
    }

    @Override
    public void setResponseHeader(String name, String value) {
        routingContext.response().putHeader(name, value);
    }

    @Override
    public Map<String, String> getResponseHeaders() {
        Map<String, String> headers = routingContext.response().headers().entries().stream()
                .collect(Collectors.toMap((Function<Map.Entry<String, String>, String>) Map.Entry::getKey,
                        (Function<Map.Entry<String, String>, String>) Map.Entry::getValue));
        return headers;
    }

    @Override
    public String getResponseLocation() {
        return getResponseHeaders().get(HttpConstants.LOCATION_HEADER);
    }

    @Override
    public void setResponseContentType(String s) {
        routingContext.response().headers().add("Content-Type", s);
    }

    @Override
    public String getServerName() {
        return serverName;
    }

    @Override
    public int getServerPort() {
        return serverPort;
    }

    @Override
    public String getScheme() {
        return scheme;
    }

    @Override
    public boolean isSecure() {
        return getScheme().equals("https");
    }

    @Override
    public String getFullRequestURL() {
        return fullUrl;
    }

    @Override
    public Collection<Cookie> getRequestCookies() {
        return routingContext.cookies().stream().map(cookie -> {
            final Cookie p4jCookie = new Cookie(cookie.getName(), cookie.getValue());
            p4jCookie.setDomain(cookie.getDomain());
            p4jCookie.setPath(cookie.getPath());
            return p4jCookie;
        }).collect(Collectors.toList());
    }

    @Override
    public void addResponseCookie(Cookie cookie) {
        routingContext.addCookie(io.vertx.ext.web.Cookie.cookie(cookie.getName(), cookie.getValue()));
    }

    @Override
    public String getPath() {
        return routingContext.request().path();
    }

    public Pac4jUser getVertxUser() {
        return (Pac4jUser) routingContext.user();
    }

    public void removeVertxUser() {
        routingContext.clearUser();
    }

    public void setVertxUser(final Pac4jUser pac4jUser) {
        routingContext.setUser(pac4jUser);
    }

}