Skip to content

WebSocket Server#14817

Closed
LyzardKing wants to merge 7 commits into
JabRef:mainfrom
LyzardKing:main
Closed

WebSocket Server#14817
LyzardKing wants to merge 7 commits into
JabRef:mainfrom
LyzardKing:main

Conversation

@LyzardKing

@LyzardKing LyzardKing commented Jan 6, 2026

Copy link
Copy Markdown
Collaborator

User description

This PR adds a websocket for remote communication. Specifically to link with browsers (replacing the problematic native messaging).

A prototype extension is available at: https://github.com/LyzardKing/JabRef-Connector
Updating the old one required too many changes, so the new version exists (for now).

It works (I'm running it from the repo myself), but any opinions and comments are more than welcome.

Steps to test

Running Jabref, in the General Settings page -> Single Instance -> Enable WebSocket Server ...
The default port is 23116 in both JabRef and the extension (no reason, can be changed).

The md file shows how to quickly test it from a script. I added a simple unit test.

Mandatory checks

  • I own the copyright of the code submitted and I license it under the MIT license
  • I manually tested my changes in running JabRef (always required)
  • I added JUnit tests for changes (if applicable)
  • [.] I added screenshots in the PR description (if change is visible to the user)
  • [.] I described the change in CHANGELOG.md in a way that is understandable for the average user (if change is visible to the user)
  • [.] I checked the user documentation: Is the information available and up to date? If not, I created an issue at https://github.com/JabRef/user-documentation/issues or, even better, I submitted a pull request updating file(s) in https://github.com/JabRef/user-documentation/tree/main/en.

PR Type

Enhancement


Description

  • Adds WebSocket server for browser extension communication

  • Implements RFC 6455 WebSocket protocol with JSON message handling

  • Adds GUI settings to enable/disable WebSocket server and configure port

  • Supports commands: ping, focus, open, and add BibTeX entries


Diagram Walkthrough

flowchart LR
  A["Browser Extension"] -->|"WebSocket Connection"| B["WebSocketListenerServer"]
  B -->|"RFC 6455 Protocol"| C["Message Handler"]
  C -->|"JSON Commands"| D["JabRef Core"]
  D -->|"ping/focus/open/add"| E["Response"]
  E -->|"JSON Response"| A
  F["Preferences UI"] -->|"Enable/Configure"| B
  G["RemoteListenerServerManager"] -->|"Lifecycle Management"| B
Loading

File Walkthrough

Relevant files
Enhancement
8 files
WebSocketListenerServer.java
WebSocket server implementation with RFC 6455 protocol     
+288/-0 
WebSocketListenerServerThread.java
Thread wrapper for WebSocket server lifecycle management 
+27/-0   
RemoteListenerServerManager.java
Add WebSocket server management methods and lifecycle       
+48/-1   
RemotePreferences.java
Add WebSocket port and enable properties with accessors   
+34/-1   
GeneralTabViewModel.java
Add WebSocket server property bindings and validation       
+46/-0   
GeneralTab.java
Add WebSocket server checkbox and port field to UI             
+7/-0     
GeneralTab.fxml
Add WebSocket server UI controls to preferences layout     
+4/-0     
JabRefGUI.java
Start WebSocket server during application initialization 
+3/-0     
Configuration changes
1 files
JabRefCliPreferences.java
Add WebSocket port and enable settings to preferences       
+9/-1     
Documentation
2 files
JabRef_en.properties
Add English localization for WebSocket server setting       
+1/-0     
websocket-server.md
Add WebSocket server documentation with examples                 
+230/-0 
Tests
2 files
RemotePreferencesTest.java
Update test to include WebSocket port parameters                 
+1/-1     
WebSocketListenerServerTest.java
Add comprehensive WebSocket server unit tests                       
+170/-0 

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jan 6, 2026

Copy link
Copy Markdown
Contributor

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🔴
Unauthenticated local access

Description: The WebSocket server binds to loopback address but accepts connections without
authentication, allowing any local process to send commands that manipulate JabRef's
state, including importing arbitrary files and adding BibTeX entries.
WebSocketListenerServer.java [36-36]

Referred Code
this.serverSocket = new ServerSocket(port, 1, java.net.InetAddress.getLoopbackAddress());
LOGGER.info("WebSocket server started on port {}", port);
Command injection vulnerability

Description: The handleTextMessage method processes commands without validating the source or content,
enabling command injection through the argument field which is passed directly to
handleCommandLineArguments with user-controlled file paths and BibTeX content.
WebSocketListenerServer.java [189-224]

Referred Code
private String handleTextMessage(String message) {
    try {
        // Parse JSON-like message (simple parsing without external dependencies)
        String command = extractJsonValue(message, "command");
        String argument = extractJsonValue(message, "argument");

        LOGGER.debug("Processing command: {} with argument: {}", command, argument);

        return switch (command) {
            case "ping" ->
                    "{\"status\":\"success\",\"response\":\"pong\"}";
            case "focus" -> {
                messageHandler.handleCommandLineArguments(new String[] {"--focus"});
                yield "{\"status\":\"success\",\"response\":\"focused\"}";
            }
            case "open" -> {
                if (argument != null && !argument.isEmpty()) {
                    messageHandler.handleCommandLineArguments(new String[] {"--import", argument});
                    yield "{\"status\":\"success\",\"response\":\"opened\"}";
                }
                yield "{\"status\":\"error\",\"message\":\"No file specified\"}";


 ... (clipped 15 lines)
Resource exhaustion risk

Description: The WebSocket connection handling lacks timeout mechanisms and resource limits, allowing a
malicious local client to hold connections indefinitely or exhaust server resources
through repeated connections.
WebSocketListenerServer.java [62-76]

Referred Code
private void handleConnection(Socket clientSocket) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), StandardCharsets.UTF_8));
    OutputStream output = clientSocket.getOutputStream();

    // Perform WebSocket handshake
    if (!performHandshake(reader, output)) {
        LOGGER.warn("WebSocket handshake failed");
        return;
    }

    LOGGER.debug("WebSocket handshake successful");

    // Handle WebSocket messages
    handleWebSocketMessages(clientSocket, output);
}
Unsafe frame parsing

Description: The WebSocket frame parsing implementation does not validate frame size limits or handle
malformed frames securely, potentially allowing buffer overflow or denial of service
through crafted WebSocket frames with extreme payload lengths.
WebSocketListenerServer.java [124-186]

Referred Code
byte[] buffer = new byte[4096];
int bytesRead;

while (!Thread.interrupted() && (bytesRead = clientSocket.getInputStream().read(buffer)) != -1) {
    if (bytesRead < 2) {
        continue;
    }

    // Parse WebSocket frame
    byte firstByte = buffer[0];
    byte secondByte = buffer[1];

    boolean fin = (firstByte & 0x80) != 0;
    int opcode = firstByte & 0x0F;
    boolean masked = (secondByte & 0x80) != 0;
    int payloadLength = secondByte & 0x7F;

    int maskOffset = 2;

    // Handle extended payload length
    if (payloadLength == 126) {


 ... (clipped 42 lines)
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

🔴
Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Silent Exception Handling: The extractJsonValue method catches all exceptions and only logs them at debug level
without proper error propagation or handling context.

Referred Code
private @Nullable String extractJsonValue(String json, String key) {
    try {
        JsonElement parsed = JsonParser.parseString(json);
        if (!parsed.isJsonObject()) {
            return null;
        }
        JsonObject obj = parsed.getAsJsonObject();
        if (!obj.has(key) || obj.get(key).isJsonNull()) {
            return null;
        }
        return obj.get(key).getAsString();
    } catch (Exception e) {
        LOGGER.debug("Failed to parse JSON in WebSocket message: {}", e.toString());
        return null;
    }
}

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status:
Command Exposure Risk: Error response exposes the exact command name received from the client in the error
message, potentially revealing internal command structure.

Referred Code
            "{\"status\":\"error\",\"message\":\"Unknown command: " + command + "\"}";
};

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Sensitive Data Logging: The complete WebSocket message content is logged at debug level, which may contain
sensitive BibTeX entries or file paths from users.

Referred Code
LOGGER.debug("Received WebSocket message: {}", message);

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Missing Input Validation: The argument parameter from WebSocket messages is passed directly to command handlers
without validation, sanitization, or length checks, creating injection risks.

Referred Code
private String handleTextMessage(String message) {
    try {
        // Parse JSON-like message (simple parsing without external dependencies)
        String command = extractJsonValue(message, "command");
        String argument = extractJsonValue(message, "argument");

        LOGGER.debug("Processing command: {} with argument: {}", command, argument);

        return switch (command) {
            case "ping" ->
                    "{\"status\":\"success\",\"response\":\"pong\"}";
            case "focus" -> {
                messageHandler.handleCommandLineArguments(new String[] {"--focus"});
                yield "{\"status\":\"success\",\"response\":\"focused\"}";
            }
            case "open" -> {
                if (argument != null && !argument.isEmpty()) {
                    messageHandler.handleCommandLineArguments(new String[] {"--import", argument});
                    yield "{\"status\":\"success\",\"response\":\"opened\"}";
                }
                yield "{\"status\":\"error\",\"message\":\"No file specified\"}";


 ... (clipped 15 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Missing Audit Logging: WebSocket connections and command executions lack comprehensive audit trails including
user context, timestamps, and action outcomes for security analysis.

Referred Code
            try (Socket clientSocket = serverSocket.accept()) {
                LOGGER.debug("WebSocket client connected from {}", clientSocket.getRemoteSocketAddress());
                handleConnection(clientSocket);
            } catch (SocketException e) {
                if (serverSocket.isClosed()) {
                    LOGGER.debug("WebSocket server socket closed");
                    break;
                }
                LOGGER.error("Socket error in WebSocket server", e);
            } catch (IOException e) {
                LOGGER.error("Error handling WebSocket connection", e);
            }
        }
    } finally {
        closeServerSocket();
    }
}

private void handleConnection(Socket clientSocket) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(), StandardCharsets.UTF_8));
    OutputStream output = clientSocket.getOutputStream();


 ... (clipped 160 lines)

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jan 6, 2026

Copy link
Copy Markdown
Contributor

PR Code Suggestions ✨

Latest suggestions up to 8a8db97

CategorySuggestion                                                                                                                                    Impact
Security
Validate file paths for security

Validate and sanitize the file path provided to the open command to prevent path
traversal security vulnerabilities.

jablib/src/main/java/org/jabref/logic/remote/server/WebSocketListenerServer.java [234-240]

 case "open" -> {
     if (argument != null && !argument.isEmpty()) {
-        messageHandler.handleCommandLineArguments(new String[] {"--import", argument});
-        yield "{\"status\":\"success\",\"response\":\"opened\"}";
+        try {
+            Path filePath = Path.of(argument).toAbsolutePath().normalize();
+            if (!filePath.startsWith(System.getProperty("user.home"))) {
+                yield "{\"status\":\"error\",\"message\":\"Invalid file path\"}";
+            }
+            messageHandler.handleCommandLineArguments(new String[] {"--import", filePath.toString()});
+            yield "{\"status\":\"success\",\"response\":\"opened\"}";
+        } catch (Exception e) {
+            yield "{\"status\":\"error\",\"message\":\"Invalid file path\"}";
+        }
     }
     yield "{\"status\":\"error\",\"message\":\"No file specified\"}";
 }
  • Apply / Chat
Suggestion importance[1-10]: 9

__

Why: This is a critical security suggestion that addresses a potential path traversal vulnerability in the newly added open command handler, preventing unauthorized file access.

High
Incremental [*]
Limit maximum WebSocket payload size

Add a maximum payload size limit in handleWebSocketMessages to prevent memory
exhaustion attacks. For example, limit the payload to 10MB and reject frames
that exceed this size.

jablib/src/main/java/org/jabref/logic/remote/server/WebSocketListenerServer.java [123-184]

+private static final int MAX_PAYLOAD_SIZE = 10 * 1024 * 1024; // 10MB
+
 private void handleWebSocketMessages(Socket clientSocket, OutputStream output) throws IOException {
     while (!Thread.interrupted() && !clientSocket.isClosed()) {
         // Read the first two bytes to get FIN, opcode, and payload length
         byte[] header = clientSocket.getInputStream().readNBytes(2);
         if (header.length < 2) {
             break; // Connection closed
         }
         ...
         // Validate payload size for array allocation
-        if (payloadLength > Integer.MAX_VALUE) {
+        if (payloadLength > MAX_PAYLOAD_SIZE) {
             LOGGER.warn("WebSocket payload too large: {}", payloadLength);
             break;
         }
         int intPayloadLength = (int) payloadLength;

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 8

__

Why: This suggestion correctly identifies a potential memory exhaustion vulnerability by allowing excessively large WebSocket payloads and proposes a sensible limit to mitigate it, which is a valuable security improvement.

Medium
  • More

Previous suggestions

✅ Suggestions up to commit 395db73
CategorySuggestion                                                                                                                                    Impact
Possible issue
Fix incomplete WebSocket frame reads
Suggestion Impact:The commit directly implements the suggested refactoring. It replaces the buffer-based read() approach with readNBytes() for reading WebSocket frame headers and extended payload lengths, ensuring complete frame reads. The changes include: switching from buffer array to header array, using readNBytes(2) for initial header, properly handling extended payload lengths with readNBytes(2) and readNBytes(8), changing payloadLength to long type, and adding connection closed checks.

code diff:

-        byte[] buffer = new byte[4096];
-        int bytesRead;
-
-        while (!Thread.interrupted() && (bytesRead = clientSocket.getInputStream().read(buffer)) != -1) {
-            if (bytesRead < 2) {
-                continue;
-            }
-
-            // Parse WebSocket frame
-            byte firstByte = buffer[0];
-            byte secondByte = buffer[1];
+        while (!Thread.interrupted() && !clientSocket.isClosed()) {
+            // Read the first two bytes to get FIN, opcode, and payload length
+            byte[] header = clientSocket.getInputStream().readNBytes(2);
+            if (header.length < 2) {
+                break; // Connection closed
+            }
+
+            byte firstByte = header[0];
+            byte secondByte = header[1];
 
             boolean fin = (firstByte & 0x80) != 0;
             int opcode = firstByte & 0x0F;
             boolean masked = (secondByte & 0x80) != 0;
-            int payloadLength = secondByte & 0x7F;
-
-            int maskOffset = 2;
+            long payloadLength = secondByte & 0x7F;
 
             // Handle extended payload length
             if (payloadLength == 126) {
-                payloadLength = ((buffer[2] & 0xFF) << 8) | (buffer[3] & 0xFF);
-                maskOffset = 4;
+                byte[] extendedPayloadLengthBytes = clientSocket.getInputStream().readNBytes(2);
+                if (extendedPayloadLengthBytes.length < 2) {
+                    break;
+                }
+                payloadLength = ((extendedPayloadLengthBytes[0] & 0xFF) << 8) | (extendedPayloadLengthBytes[1] & 0xFF);
             } else if (payloadLength == 127) {
-                // For very large payloads (not typically needed for our use case)
-                maskOffset = 10;
+                byte[] extendedPayloadLengthBytes = clientSocket.getInputStream().readNBytes(8);
+                if (extendedPayloadLengthBytes.length < 8) {
+                    break;
+                }
+                payloadLength = java.nio.ByteBuffer.wrap(extendedPayloadLengthBytes).getLong();
             }

Refactor the WebSocket message handling to correctly read complete frames from
the TCP stream, preventing errors from fragmented packets.

jablib/src/main/java/org/jabref/logic/remote/server/WebSocketListenerServer.java [123-156]

     private void handleWebSocketMessages(Socket clientSocket, OutputStream output) throws IOException {
-        byte[] buffer = new byte[4096];
-        int bytesRead;
-
-        while (!Thread.interrupted() && (bytesRead = clientSocket.getInputStream().read(buffer)) != -1) {
-            if (bytesRead < 2) {
-                continue;
+        while (!Thread.interrupted() && !clientSocket.isClosed()) {
+            // Read the first two bytes to get FIN, opcode, and payload length
+            byte[] header = clientSocket.getInputStream().readNBytes(2);
+            if (header.length < 2) {
+                break; // Connection closed
             }
 
-            // Parse WebSocket frame
-            byte firstByte = buffer[0];
-            byte secondByte = buffer[1];
+            byte firstByte = header[0];
+            byte secondByte = header[1];
 
             boolean fin = (firstByte & 0x80) != 0;
             int opcode = firstByte & 0x0F;
             boolean masked = (secondByte & 0x80) != 0;
-            int payloadLength = secondByte & 0x7F;
-
-            int maskOffset = 2;
+            long payloadLength = secondByte & 0x7F;
 
             // Handle extended payload length
             if (payloadLength == 126) {
-                payloadLength = ((buffer[2] & 0xFF) << 8) | (buffer[3] & 0xFF);
-                maskOffset = 4;
+                byte[] extendedPayloadLengthBytes = clientSocket.getInputStream().readNBytes(2);
+                if (extendedPayloadLengthBytes.length < 2) {
+                    break;
+                }
+                payloadLength = ((extendedPayloadLengthBytes[0] & 0xFF) << 8) | (extendedPayloadLengthBytes[1] & 0xFF);
             } else if (payloadLength == 127) {
-                // For very large payloads (not typically needed for our use case)
-                maskOffset = 10;
+                byte[] extendedPayloadLengthBytes = clientSocket.getInputStream().readNBytes(8);
+                if (extendedPayloadLengthBytes.length < 8) {
+                    break;
+                }
+                payloadLength = java.nio.ByteBuffer.wrap(extendedPayloadLengthBytes).getLong();
             }
 
             // Close frame
             if (opcode == 0x08) {
                 LOGGER.debug("WebSocket close frame received");
                 break;
             }
 ...
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a critical bug in the WebSocket frame parsing logic where incomplete TCP packets are not handled, which would lead to connection failures.

High
Add null check for command
Suggestion Impact:The suggestion was directly implemented in the commit. A null check for the command variable was added at lines 59-62, which returns an error message if command is null, exactly as suggested. The only minor difference is the addition of a debug log statement.

code diff:

+            if (command == null) {
+                LOGGER.debug("No command found in WebSocket message");
+                return "{\"status\":\"error\",\"message\":\"Command not specified\"}";
+            }

Add a null check for the command variable in handleTextMessage before the switch
statement to prevent a potential NullPointerException.

jablib/src/main/java/org/jabref/logic/remote/server/WebSocketListenerServer.java [189-225]

     private String handleTextMessage(String message) {
         try {
             // Parse JSON-like message (simple parsing without external dependencies)
             String command = extractJsonValue(message, "command");
             String argument = extractJsonValue(message, "argument");
 
             LOGGER.debug("Processing command: {} with argument: {}", command, argument);
+
+            if (command == null) {
+                return "{\"status\":\"error\",\"message\":\"Command not specified\"}";
+            }
 
             return switch (command) {
                 case "ping" ->
                         "{\"status\":\"success\",\"response\":\"pong\"}";
                 case "focus" -> {
                     messageHandler.handleCommandLineArguments(new String[] {"--focus"});
                     yield "{\"status\":\"success\",\"response\":\"focused\"}";
                 }
                 case "open" -> {
                     if (argument != null && !argument.isEmpty()) {
                         messageHandler.handleCommandLineArguments(new String[] {"--import", argument});
                         yield "{\"status\":\"success\",\"response\":\"opened\"}";
                     }
                     yield "{\"status\":\"error\",\"message\":\"No file specified\"}";
                 }
                 case "add" -> {
                     if (argument != null && !argument.isEmpty()) {
                         messageHandler.handleCommandLineArguments(new String[] {"--importBibtex", argument});
                         yield "{\"status\":\"success\",\"response\":\"added\"}";
                     }
                     yield "{\"status\":\"error\",\"message\":\"No BibTeX entry specified\"}";
                 }
                 default ->
                         "{\"status\":\"error\",\"message\":\"Unknown command: " + command + "\"}";
             };
         } catch (Exception e) {
             LOGGER.error("Error processing WebSocket message", e);
             return "{\"status\":\"error\",\"message\":\"Internal error\"}";
         }
     }

[Suggestion processed]

Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a potential NullPointerException when the command is null, which would crash the message processing logic, and provides a valid fix.

Medium
Learned
best practice
Cache input stream reference
Suggestion Impact:The suggestion was partially implemented. While the commit does cache the input stream reference, it does so inside the while loop (line 81: `java.io.InputStream in = clientSocket.getInputStream()`) rather than before the loop as suggested. However, the commit significantly refactored the code to use readNBytes() instead of read() with a buffer, which changes the approach but still addresses the efficiency concern by reducing redundant operations.

code diff:

+                java.io.InputStream in = clientSocket.getInputStream();

Consider pre-allocating resources and collecting frame metadata before
processing to reduce redundant operations within the message loop. This can
improve efficiency when handling multiple WebSocket frames.

jablib/src/main/java/org/jabref/logic/remote/server/WebSocketListenerServer.java [123-130]

 private void handleWebSocketMessages(Socket clientSocket, OutputStream output) throws IOException {
     byte[] buffer = new byte[4096];
     int bytesRead;
+    InputStream inputStream = clientSocket.getInputStream();
 
-    while (!Thread.interrupted() && (bytesRead = clientSocket.getInputStream().read(buffer)) != -1) {
+    while (!Thread.interrupted() && (bytesRead = inputStream.read(buffer)) != -1) {
         if (bytesRead < 2) {
             continue;
         }
         ...
     }
 }
Suggestion importance[1-10]: 6

__

Why:
Relevant best practice - Optimize file system operations by collecting all required data first, then performing a single traversal of directories instead of multiple nested iterations. This pattern applies when searching for files or validating file existence across multiple paths.

Low

String argument = extractJsonValue(message, "argument");

LOGGER.debug("Processing command: {} with argument: {}", command, argument);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: Add null check for command

Suggested change
if (command == null) {
return "{\"status\":\"error\",\"message\":\"Command not specified\"}";
}

@github-actions github-actions Bot added the status: changes-required Pull requests that are not yet complete label Jan 6, 2026
@jabref-machine

Copy link
Copy Markdown
Collaborator

You committed your code on the main brach of your fork. This is a bad practice. The right way is to branch out from main, work on your patch/feature in that new branch, and then get that branch merged via the pull request (see GitHub flow).

For this pull request, this is OK. For subsequent pull requests, please start with a different branch with a proper branch name. See CONTRIBUTING.md for more details.

@Siedlerchr Siedlerchr changed the title Main WebSocket Server Jan 6, 2026
@Siedlerchr

Copy link
Copy Markdown
Member

Happy New Year! Nice to hear from you again!
Do you know about the HTTP Server we have now as well? CAn that be used?

@jabref-machine

Copy link
Copy Markdown
Collaborator

Note that your PR will not be reviewed/accepted until you have gone through the mandatory checks in the description and marked each of them them exactly in the format of [x] (done), [ ] (not done yet) or [/] (not applicable). Please adhere to our pull request template.

@LyzardKing

LyzardKing commented Jan 6, 2026

Copy link
Copy Markdown
Collaborator Author

Hi @Siedlerchr! Happy new year!
Yes, it's been a while... my bad.

I don't think the http server can be used as is, as most of what the websocket one does is deal with the handshake and data format. I'm no expert however, so I might be wrong.

Currently on Chrome the sample addon works. It is also built on the zotero translators.
Firefox is a bit more complex, mainly with the different implementations of MV3.

EDIT: Actually it might be possible... I'll give it a closer look

@LyzardKing

Copy link
Copy Markdown
Collaborator Author

@Siedlerchr

https://github.com/LyzardKing/jabref/tree/websocket

Here is the version that reuses the http server. I added a few libraries here and there (grizzly-websockets and jakarta.servlet-api), and add an overloaded run function to Server so it would accept the remoteMessageHandler.

Still needs testing, but it interfaces correclty with the extension. I'll close this PR and open a new one.

@Siedlerchr

Copy link
Copy Markdown
Member

Cool! Guess @koppor or @palukku can also help here

@LyzardKing

Copy link
Copy Markdown
Collaborator Author

Replaced by #14823

@LyzardKing LyzardKing closed this Jan 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Review effort 4/5 status: changes-required Pull requests that are not yet complete

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants