mirror of
https://github.com/plexusorg/Module-HTTPD.git
synced 2026-06-04 09:06:54 +00:00
126 lines
3.9 KiB
Java
126 lines
3.9 KiB
Java
package dev.plex.request;
|
|
|
|
import dev.plex.HTTPDModule;
|
|
import dev.plex.logging.Log;
|
|
import dev.plex.request.impl.PlayerInventoryBroadcaster;
|
|
import jakarta.servlet.AsyncContext;
|
|
import jakarta.servlet.AsyncEvent;
|
|
import jakarta.servlet.AsyncListener;
|
|
import jakarta.servlet.ServletException;
|
|
import jakarta.servlet.http.HttpServlet;
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
|
|
import java.io.IOException;
|
|
import java.io.PrintWriter;
|
|
import java.util.UUID;
|
|
|
|
public class PlayerInventoryStreamServlet extends HttpServlet
|
|
{
|
|
private final HTTPDModule module;
|
|
private final PlayerInventoryBroadcaster broadcaster;
|
|
|
|
public PlayerInventoryStreamServlet(HTTPDModule module, PlayerInventoryBroadcaster broadcaster)
|
|
{
|
|
this.module = module;
|
|
this.broadcaster = broadcaster;
|
|
}
|
|
|
|
@Override
|
|
protected void doGet(HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException
|
|
{
|
|
if (AbstractServlet.currentStaff(module, request) == null)
|
|
{
|
|
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
|
return;
|
|
}
|
|
|
|
String uuidStr = request.getParameter("uuid");
|
|
if (uuidStr == null)
|
|
{
|
|
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
|
return;
|
|
}
|
|
final UUID uuid;
|
|
try
|
|
{
|
|
uuid = UUID.fromString(uuidStr);
|
|
}
|
|
catch (IllegalArgumentException e)
|
|
{
|
|
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
|
return;
|
|
}
|
|
|
|
String ipAddress = request.getRemoteAddr();
|
|
if ("127.0.0.1".equals(ipAddress))
|
|
{
|
|
String forwarded = request.getHeader("X-FORWARDED-FOR");
|
|
if (forwarded != null) ipAddress = forwarded;
|
|
}
|
|
Log.log(ipAddress + " opened inventory stream for " + uuid);
|
|
|
|
if (broadcaster.atCapacity())
|
|
{
|
|
response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
|
|
response.setHeader("Retry-After", "30");
|
|
return;
|
|
}
|
|
|
|
response.setStatus(HttpServletResponse.SC_OK);
|
|
response.setContentType("text/event-stream");
|
|
response.setCharacterEncoding("UTF-8");
|
|
response.setHeader("Cache-Control", "no-cache, no-transform");
|
|
response.setHeader("Connection", "keep-alive");
|
|
response.setHeader("X-Accel-Buffering", "no");
|
|
|
|
final AsyncContext ctx = request.startAsync();
|
|
ctx.setTimeout(0L);
|
|
ctx.addListener(new AsyncListener()
|
|
{
|
|
@Override public void onComplete(AsyncEvent event) { broadcaster.removeSubscriber(uuid, ctx); }
|
|
@Override public void onTimeout(AsyncEvent event) { broadcaster.removeSubscriber(uuid, ctx); }
|
|
@Override public void onError(AsyncEvent event) { broadcaster.removeSubscriber(uuid, ctx); }
|
|
@Override public void onStartAsync(AsyncEvent event) {}
|
|
});
|
|
|
|
PrintWriter writer;
|
|
try
|
|
{
|
|
writer = response.getWriter();
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
ctx.complete();
|
|
return;
|
|
}
|
|
|
|
if (!broadcaster.addSubscriber(uuid, ctx, writer))
|
|
{
|
|
response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
|
|
ctx.complete();
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
writer.write("retry: 5000\n\n");
|
|
writer.write("data: ");
|
|
writer.write(broadcaster.currentPayload(uuid));
|
|
writer.write("\n\n");
|
|
writer.flush();
|
|
if (writer.checkError())
|
|
{
|
|
broadcaster.removeSubscriber(uuid, ctx);
|
|
ctx.complete();
|
|
}
|
|
}
|
|
catch (Throwable t)
|
|
{
|
|
broadcaster.removeSubscriber(uuid, ctx);
|
|
try { ctx.complete(); } catch (Throwable ignored) {}
|
|
}
|
|
}
|
|
}
|