package io.vertx.ext.web.handler.impl;
import io.vertx.core.VertxException;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.shareddata.impl.ClusterSerializable;
import io.vertx.ext.auth.User;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.impl.Utils;
import java.nio.charset.StandardCharsets;
public class UserHolder implements ClusterSerializable {
private RoutingContext context;
private User user;
public UserHolder() {
}
public UserHolder(RoutingContext context) {
this.context = context;
}
public synchronized void refresh(RoutingContext context) {
if (this.context != null) {
user = this.context.user();
}
this.context = context;
if (user != null) {
this.context.setUser(user);
}
}
@Override
public void writeToBuffer(Buffer buffer) {
final User user;
synchronized (this) {
user = context != null ? context.user() : this.user;
context = null;
}
if (user instanceof ClusterSerializable) {
buffer.appendByte((byte)1);
String className = user.getClass().getName();
byte[] bytes = className.getBytes(StandardCharsets.UTF_8);
buffer.appendInt(bytes.length);
buffer.appendBytes(bytes);
ClusterSerializable cs = (ClusterSerializable)user;
cs.writeToBuffer(buffer);
} else {
buffer.appendByte((byte)0);
}
}
@Override
public int readFromBuffer(int pos, Buffer buffer) {
byte b = buffer.getByte(pos++);
if (b == (byte)1) {
int len = buffer.getInt(pos);
pos += 4;
byte[] bytes = buffer.getBytes(pos, pos + len);
pos += len;
String className = new String(bytes, StandardCharsets.UTF_8);
try {
Class<?> clazz = Utils.getClassLoader().loadClass(className);
if (!ClusterSerializable.class.isAssignableFrom(clazz)) {
throw new ClassCastException(className + " is not ClusterSerializable");
}
ClusterSerializable obj = (ClusterSerializable) clazz.getDeclaredConstructor().newInstance();
pos = obj.readFromBuffer(pos, buffer);
synchronized (this) {
user = (User) obj;
context = null;
}
} catch (Exception e) {
throw new VertxException(e);
}
} else {
synchronized (this) {
user = null;
context = null;
}
}
return pos;
}
}