package act.handler;
/*-
* #%L
* ACT Framework
* %%
* Copyright (C) 2014 - 2017 ActFramework
* %%
* 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.
* #L%
*/
import act.app.ActionContext;
import act.handler.builtin.AlwaysNotFound;
import act.handler.builtin.UnknownHttpMethodHandler;
import act.route.Router;
import act.security.CORS;
import act.util.DestroyableBase;
import org.osgl.http.H;
import org.osgl.util.C;
import org.osgl.util.S;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* Process HTTP OPTIONS request
*/
public class OptionsInfoBase extends DestroyableBase {
private Router router;
private ConcurrentMap<String, RequestHandler> handlers = new ConcurrentHashMap<String, RequestHandler>();
public OptionsInfoBase(Router router) {
this.router = router;
}
public RequestHandler optionHandler(CharSequence path, ActionContext context) {
String s = S.string(path);
RequestHandler handler = handlers.get(s);
if (null == handler) {
handler = createHandler(path, context);
handlers.putIfAbsent(s, handler);
}
return handler;
}
private RequestHandler createHandler(CharSequence path, ActionContext context) {
if (!router.app().config().corsEnabled()) {
return UnknownHttpMethodHandler.INSTANCE;
}
C.List<H.Method> allowMethods = C.newList();
C.List<CORS.Spec> corsSpecs = C.newList();
for (H.Method method: router.supportedHttpMethods()) {
RequestHandler handler;
handler = router.getInvoker(method, path, context);
if (handler instanceof AlwaysNotFound) {
continue;
}
allowMethods.add(method);
CORS.Spec corsSpec = handler.corsSpec();
if (corsSpec != CORS.Spec.DUMB) {
corsSpecs.add(corsSpec);
}
}
if (allowMethods.isEmpty()) {
return AlwaysNotFound.INSTANCE;
}
CORS.Spec corsSpec = CORS.spec(allowMethods);
for (CORS.Spec spec : corsSpecs) {
corsSpec = corsSpec.chain(spec);
}
return new OptionsRequestHandler(corsSpec);
}
}