protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
SerializationService serializationService = Aura.getSerializationService();
LoggingService loggingService = Aura.getLoggingService();
ContextService contextService = Aura.getContextService();
ServerService serverService = Aura.getServerService();
AuraContext context = contextService.getCurrentContext();
response.setCharacterEncoding(UTF_ENCODING);
boolean written = false;
setNoCache(response);
try {
if (context.getFormat() != Format.JSON) {
throw new AuraRuntimeException("Invalid request, post must use JSON");
}
response.setContentType(getContentType(Format.JSON));
String msg = messageParam.get(request);
if (msg == null) {
throw new AuraRuntimeException("Invalid request, no message");
}
//
// handle transaction beacon JSON data
// FIXME: this should be an action.
//
String beaconData = beaconParam.get(request);
if (!"undefined".equals(beaconData) && !AuraTextUtil.isNullEmptyOrWhitespace(beaconData)) {
loggingService.setValue(LoggingService.BEACON_DATA, new JsonReader().read(beaconData));
}
String fwUID = Aura.getConfigAdapter().getAuraFrameworkNonce();
if (!fwUID.equals(context.getFrameworkUID())) {
throw new ClientOutOfSyncException("Framework has been updated");
}
context.setFrameworkUID(fwUID);
Message message;
loggingService.startTimer(LoggingService.TIMER_DESERIALIZATION);
try {
message = serializationService.read(new StringReader(msg), Message.class);
} finally {
loggingService.stopTimer(LoggingService.TIMER_DESERIALIZATION);
}
// The bootstrap action cannot not have a CSRF token so we let it
// through
boolean isBootstrapAction = false;
if (message.getActions().size() == 1) {
Action action = message.getActions().get(0);
String name = action.getDescriptor().getQualifiedName();
if (name.equals("aura://ComponentController/ACTION$getApplication")
|| (name.equals("aura://ComponentController/ACTION$getComponent") && !isProductionMode(context
.getMode()))) {
isBootstrapAction = true;
}
}
if (!isBootstrapAction) {
validateCSRF(csrfToken.get(request));
}
DefDescriptor<? extends BaseComponentDef> applicationDescriptor = context.getApplicationDescriptor();
// Knowing the app, we can do the HTTP headers, so of which depend on
// the app in play, so we couldn't do this
setBasicHeaders(applicationDescriptor, request, response);
if (applicationDescriptor != null) {
// ClientOutOfSync will drop down.
try {
Aura.getDefinitionService().updateLoaded(applicationDescriptor);
} catch (QuickFixException qfe) {
//
// ignore quick fix. If we got a 'new' quickfix, it will be thrown as
// a client out of sync exception, since the UID will not match.
//
}
if (!context.isTestMode() && !context.isDevMode()) {
assertAccess(applicationDescriptor.getDef());
}
}
Map<String, Object> attributes = null;
if (isBootstrapAction) {
attributes = Maps.newHashMap();
attributes.put("token", getToken());
}
PrintWriter out = response.getWriter();
written = true;
out.write(CSRF_PROTECT);
serverService.run(message, context, out, attributes);
} catch (RequestParam.InvalidParamException ipe) {
handleServletException(new SystemErrorException(ipe), false, context, request, response, false);
return;
} catch (RequestParam.MissingParamException mpe) {
handleServletException(new SystemErrorException(mpe), false, context, request, response, false);