Line data Source code
1 : // Copyright (C) 2012 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.httpd; 16 : 17 : import com.google.gerrit.common.Nullable; 18 : import com.google.gerrit.server.RemotePeer; 19 : import com.google.gerrit.server.config.CanonicalWebUrl; 20 : import com.google.gerrit.server.util.RequestScopePropagator; 21 : import com.google.gerrit.server.util.ThreadLocalRequestContext; 22 : import com.google.inject.Inject; 23 : import com.google.inject.Key; 24 : import com.google.inject.Provider; 25 : import com.google.inject.servlet.ServletScopes; 26 : import com.google.inject.util.Providers; 27 : import com.google.inject.util.Types; 28 : import java.lang.reflect.ParameterizedType; 29 : import java.lang.reflect.Type; 30 : import java.net.SocketAddress; 31 : import java.util.HashMap; 32 : import java.util.Map; 33 : import java.util.concurrent.Callable; 34 : import javax.servlet.http.HttpServletRequest; 35 : 36 : /** Propagator for Guice's built-in servlet scope. */ 37 : public class GuiceRequestScopePropagator extends RequestScopePropagator { 38 : 39 : private final String url; 40 : private final SocketAddress peer; 41 : private final Provider<HttpServletRequest> request; 42 : 43 : @Inject 44 : GuiceRequestScopePropagator( 45 : @CanonicalWebUrl @Nullable Provider<String> urlProvider, 46 : @RemotePeer Provider<SocketAddress> remotePeerProvider, 47 : ThreadLocalRequestContext local, 48 : Provider<HttpServletRequest> request) { 49 7 : super(ServletScopes.REQUEST, local); 50 7 : this.url = urlProvider != null ? urlProvider.get() : null; 51 7 : this.peer = remotePeerProvider.get(); 52 7 : this.request = request; 53 7 : } 54 : 55 : /** @see RequestScopePropagator#wrap(Callable) */ 56 : // ServletScopes#continueRequest is deprecated, but it's not obvious their 57 : // recommended replacement is an appropriate drop-in solution; see 58 : // https://gerrit-review.googlesource.com/83971 59 : @SuppressWarnings("deprecation") 60 : @Override 61 : protected <T> Callable<T> wrapImpl(Callable<T> callable) { 62 7 : Map<Key<?>, Object> seedMap = new HashMap<>(); 63 : 64 : // Request scopes appear to use specific keys in their map, instead of only 65 : // providers. Add bindings for both the key to the instance directly and the 66 : // provider to the instance to be safe. 67 7 : seedMap.put(Key.get(typeOfProvider(String.class), CanonicalWebUrl.class), Providers.of(url)); 68 7 : seedMap.put(Key.get(String.class, CanonicalWebUrl.class), url); 69 : 70 7 : seedMap.put(Key.get(typeOfProvider(SocketAddress.class), RemotePeer.class), Providers.of(peer)); 71 7 : seedMap.put(Key.get(SocketAddress.class, RemotePeer.class), peer); 72 : 73 7 : Key<?> webSessionAttrKey = Key.get(WebSession.class); 74 7 : Object webSessionAttrValue = request.get().getAttribute(webSessionAttrKey.toString()); 75 7 : seedMap.put(webSessionAttrKey, webSessionAttrValue); 76 7 : seedMap.put(Key.get(typeOfProvider(WebSession.class)), Providers.of(webSessionAttrValue)); 77 : 78 7 : return ServletScopes.continueRequest(callable, seedMap); 79 : } 80 : 81 : private ParameterizedType typeOfProvider(Type type) { 82 7 : return Types.newParameterizedType(Provider.class, type); 83 : } 84 : }