mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-05-04 16:34:14 +00:00
Add some basic tracking for HTTP requests and websockets
This should allow for easier identification of misbehaving computers, which are consuming a large amount of bandwidth.
This commit is contained in:
parent
8775052dee
commit
b522af3075
@ -15,6 +15,7 @@ import dan200.computercraft.api.lua.LuaException;
|
|||||||
import dan200.computercraft.core.apis.IAPIEnvironment;
|
import dan200.computercraft.core.apis.IAPIEnvironment;
|
||||||
import dan200.computercraft.core.apis.handles.BinaryInputHandle;
|
import dan200.computercraft.core.apis.handles.BinaryInputHandle;
|
||||||
import dan200.computercraft.core.apis.handles.EncodedInputHandle;
|
import dan200.computercraft.core.apis.handles.EncodedInputHandle;
|
||||||
|
import dan200.computercraft.core.tracking.TrackingField;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@ -134,6 +135,11 @@ public class HTTPRequest implements Runnable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add request size and count to the tracker before opening the connection
|
||||||
|
m_environment.addTrackingChange( TrackingField.HTTP_REQUESTS );
|
||||||
|
m_environment.addTrackingChange( TrackingField.HTTP_UPLOAD,
|
||||||
|
getHeaderSize( connection.getRequestProperties() ) + (m_postText == null ? 0 : m_postText.length()) );
|
||||||
|
|
||||||
// Send POST text
|
// Send POST text
|
||||||
if( m_postText != null )
|
if( m_postText != null )
|
||||||
{
|
{
|
||||||
@ -178,6 +184,9 @@ public class HTTPRequest implements Runnable
|
|||||||
headers.put( header.getKey(), joiner.join( header.getValue() ) );
|
headers.put( header.getKey(), joiner.join( header.getValue() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_environment.addTrackingChange( TrackingField.HTTP_DOWNLOAD,
|
||||||
|
getHeaderSize( connection.getHeaderFields() ) + result.length );
|
||||||
|
|
||||||
InputStream contents = new ByteArrayInputStream( result );
|
InputStream contents = new ByteArrayInputStream( result );
|
||||||
ILuaObject stream = wrapStream(
|
ILuaObject stream = wrapStream(
|
||||||
m_binary ? new BinaryInputHandle( contents ) : new EncodedInputHandle( contents, connection.getContentEncoding() ),
|
m_binary ? new BinaryInputHandle( contents ) : new EncodedInputHandle( contents, connection.getContentEncoding() ),
|
||||||
@ -248,4 +257,15 @@ public class HTTPRequest implements Runnable
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static long getHeaderSize( Map<String, List<String>> headers )
|
||||||
|
{
|
||||||
|
long size = 0;
|
||||||
|
for( Map.Entry<String, List<String>> header : headers.entrySet() )
|
||||||
|
{
|
||||||
|
size += header.getKey() == null ? 0 : header.getKey().length();
|
||||||
|
for( String value : header.getValue() ) size += value == null ? 0 : value.length() + 1;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import dan200.computercraft.api.lua.ILuaObject;
|
|||||||
import dan200.computercraft.api.lua.LuaException;
|
import dan200.computercraft.api.lua.LuaException;
|
||||||
import dan200.computercraft.core.apis.HTTPAPI;
|
import dan200.computercraft.core.apis.HTTPAPI;
|
||||||
import dan200.computercraft.core.apis.IAPIEnvironment;
|
import dan200.computercraft.core.apis.IAPIEnvironment;
|
||||||
|
import dan200.computercraft.core.tracking.TrackingField;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
@ -115,14 +116,19 @@ public class WebsocketConnection extends SimpleChannelInboundHandler<Object> imp
|
|||||||
WebSocketFrame frame = (WebSocketFrame) msg;
|
WebSocketFrame frame = (WebSocketFrame) msg;
|
||||||
if( frame instanceof TextWebSocketFrame )
|
if( frame instanceof TextWebSocketFrame )
|
||||||
{
|
{
|
||||||
computer.queueEvent( MESSAGE_EVENT, new Object[] { url, ((TextWebSocketFrame) frame).text() } );
|
String data = ((TextWebSocketFrame) frame).text();
|
||||||
|
|
||||||
|
computer.addTrackingChange( TrackingField.WEBSOCKET_INCOMING, data.length() );
|
||||||
|
computer.queueEvent( MESSAGE_EVENT, new Object[]{ url, data } );
|
||||||
}
|
}
|
||||||
else if( frame instanceof BinaryWebSocketFrame )
|
else if( frame instanceof BinaryWebSocketFrame )
|
||||||
{
|
{
|
||||||
ByteBuf data = frame.content();
|
ByteBuf data = frame.content();
|
||||||
byte[] converted = new byte[data.readableBytes()];
|
byte[] converted = new byte[data.readableBytes()];
|
||||||
data.readBytes( converted );
|
data.readBytes( converted );
|
||||||
computer.queueEvent( MESSAGE_EVENT, new Object[] { url, data } );
|
|
||||||
|
computer.addTrackingChange( TrackingField.WEBSOCKET_INCOMING, converted.length );
|
||||||
|
computer.queueEvent( MESSAGE_EVENT, new Object[]{ url, converted } );
|
||||||
}
|
}
|
||||||
else if( frame instanceof CloseWebSocketFrame )
|
else if( frame instanceof CloseWebSocketFrame )
|
||||||
{
|
{
|
||||||
@ -168,6 +174,7 @@ public class WebsocketConnection extends SimpleChannelInboundHandler<Object> imp
|
|||||||
{
|
{
|
||||||
checkOpen();
|
checkOpen();
|
||||||
String text = arguments.length > 0 && arguments[0] != null ? arguments[0].toString() : "";
|
String text = arguments.length > 0 && arguments[0] != null ? arguments[0].toString() : "";
|
||||||
|
computer.addTrackingChange( TrackingField.WEBSOCKET_OUTGOING, text.length() );
|
||||||
channel.writeAndFlush( new TextWebSocketFrame( text ) );
|
channel.writeAndFlush( new TextWebSocketFrame( text ) );
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,16 @@ public class TrackingField
|
|||||||
public static final TrackingField SERVER_COUNT = TrackingField.of( "server_count", "Server task count", x -> String.format( "%4d", x ) );
|
public static final TrackingField SERVER_COUNT = TrackingField.of( "server_count", "Server task count", x -> String.format( "%4d", x ) );
|
||||||
public static final TrackingField SERVER_TIME = TrackingField.of( "server_time", "Server task time", x -> String.format( "%7.1fms", x / 1e6 ) );
|
public static final TrackingField SERVER_TIME = TrackingField.of( "server_time", "Server task time", x -> String.format( "%7.1fms", x / 1e6 ) );
|
||||||
|
|
||||||
public static final TrackingField PERIPHERAL_OPS = TrackingField.of( "peripheral", "Peripheral calls", x -> String.format( "%6d", x ) );
|
public static final TrackingField PERIPHERAL_OPS = TrackingField.of( "peripheral", "Peripheral calls", TrackingField::formatDefault );
|
||||||
public static final TrackingField FS_OPS = TrackingField.of( "fs", "Filesystem operations", x -> String.format( "%6d", x ) );
|
public static final TrackingField FS_OPS = TrackingField.of( "fs", "Filesystem operations", TrackingField::formatDefault );
|
||||||
public static final TrackingField TURTLE_OPS = TrackingField.of( "turtle", "Turtle operations", x -> String.format( "%6d", x ) );
|
public static final TrackingField TURTLE_OPS = TrackingField.of( "turtle", "Turtle operations", TrackingField::formatDefault );
|
||||||
|
|
||||||
|
public static final TrackingField HTTP_REQUESTS = TrackingField.of( "http", "HTTP requests", TrackingField::formatDefault );
|
||||||
|
public static final TrackingField HTTP_UPLOAD = TrackingField.of( "http_upload", "HTTP upload", TrackingField::formatBytes );
|
||||||
|
public static final TrackingField HTTP_DOWNLOAD = TrackingField.of( "http_download", "HTTT download", TrackingField::formatBytes );
|
||||||
|
|
||||||
|
public static final TrackingField WEBSOCKET_INCOMING = TrackingField.of( "websocket_incoming", "Websocket incoming", TrackingField::formatBytes );
|
||||||
|
public static final TrackingField WEBSOCKET_OUTGOING = TrackingField.of( "websocket_outgoing", "Websocket outgoing", TrackingField::formatBytes );
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
private final String displayName;
|
private final String displayName;
|
||||||
@ -58,4 +65,24 @@ public class TrackingField
|
|||||||
{
|
{
|
||||||
return Collections.unmodifiableMap( fields );
|
return Collections.unmodifiableMap( fields );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String formatDefault( long value )
|
||||||
|
{
|
||||||
|
return String.format( "%6d", value );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* So technically a kibibyte, but let's not argue here.
|
||||||
|
*/
|
||||||
|
private static final int KILOBYTE_SIZE = 1024;
|
||||||
|
|
||||||
|
private static final String SI_PREFIXES = "KMGT";
|
||||||
|
|
||||||
|
private static String formatBytes( long bytes )
|
||||||
|
{
|
||||||
|
if( bytes < 1024 ) return String.format( "%10d B", bytes );
|
||||||
|
int exp = (int) (Math.log( bytes ) / Math.log( KILOBYTE_SIZE ));
|
||||||
|
if( exp > SI_PREFIXES.length() ) exp = SI_PREFIXES.length();
|
||||||
|
return String.format( "%10.1f %siB", bytes / Math.pow( KILOBYTE_SIZE, exp ), SI_PREFIXES.charAt( exp - 1 ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user