-
Notifications
You must be signed in to change notification settings - Fork 0
Rename SocketServer to Server Move HTTP request handling logic to a dedicated ConnectionHandler. #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rename SocketServer to Server Move HTTP request handling logic to a dedicated ConnectionHandler. #28
Changes from all commits
dc7fd89
c1f308b
7e74b5a
ac7ff05
0090d65
d3dd7b9
26b916a
030eb5a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,22 @@ | ||
| package org.juv25d; | ||
|
|
||
| import org.juv25d.logging.ServerLogging; | ||
| import org.juv25d.parser.HttpParser; | ||
|
|
||
| import java.util.logging.Logger; | ||
|
|
||
| public class App { | ||
| public static void main(String[] args) { | ||
| SocketServer.createSocket(); | ||
| Logger logger = ServerLogging.getLogger(); | ||
| HttpParser httpParser = new HttpParser(); | ||
| DefaultConnectionHandlerFactory handlerFactory = | ||
| new DefaultConnectionHandlerFactory(httpParser, logger); | ||
|
|
||
| Server server = new Server( | ||
| logger, | ||
| handlerFactory | ||
| ); | ||
|
|
||
| server.start(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package org.juv25d; | ||
|
|
||
| import org.juv25d.parser.HttpParser; | ||
| import java.io.IOException; | ||
| import java.net.Socket; | ||
| import java.util.logging.Level; | ||
| import java.util.logging.Logger; | ||
|
|
||
| public class ConnectionHandler implements Runnable { | ||
| private final Socket socket; | ||
| private final HttpParser httpParser; | ||
| private final Logger logger; | ||
|
Comment on lines
+9
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice use of "final" - ensures immutability after construction. private final StaticFileHandler staticFileHandler;This would allow ConnectionHandler to delegate GET requests |
||
|
|
||
| public ConnectionHandler(Socket socket, HttpParser httpParser, Logger logger) { | ||
| this.socket = socket; | ||
| this.httpParser = httpParser; | ||
| this.logger = logger; | ||
|
Comment on lines
+14
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Constructor follows DI pattern well. Note:This is where I'll need to add StaticFileHandler public ConnectionHandler(Socket socket, HttpParser httpParser,
Logger logger, StaticFileHandler fileHandler) {
this.socket = socket;
this.httpParser = httpParser;
this.logger = logger;
this.staticFileHandler = fileHandler;
} |
||
| } | ||
|
|
||
| @Override | ||
| public void run() { | ||
| try (socket) { | ||
| HttpRequest request = httpParser.parse(socket.getInputStream()); | ||
|
|
||
| logger.info("Handling request: " + request.method() + " " + request.path()); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CRITICAL: This is where HTTP response logic should go Currently, the request is parsed but no response is sent back. For my PR #36 integration, I propose adding:** HttpRequest request = httpParser.parse(socket.getInputStream());
logger.info("Handling request: " + request.method() + " " + request.path());
// NEW CODE - Handle GET requests with StaticFileHandler
if (request.method().equalsIgnoreCase("GET")) {
HttpResponse response = staticFileHandler.handle(request);
HttpResponseWriter.write(socket.getOutputStream(), response);
} else {
// Return 405 Method Not Allowed for non-GET
HttpResponse response = createMethodNotAllowedResponse();
HttpResponseWriter.write(socket.getOutputStream(), response);
}Questions:
|
||
|
|
||
| } catch (IOException e) { | ||
| logger.log(Level.SEVERE, "Error while handling request", e); | ||
| } | ||
| } | ||
|
fmazmz marked this conversation as resolved.
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package org.juv25d; | ||
|
|
||
| import java.net.Socket; | ||
|
|
||
| public interface ConnectionHandlerFactory { | ||
| Runnable create(Socket socket); | ||
| } | ||
|
Comment on lines
+5
to
+7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good use of Factory pattern This interface allows for different ConnectionHandler implementations:
Suggestion: ConnectionHandler create(Socket socket);Instead of Integration note (PR #36):I'll modify |
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Factory pattern implementation looks clean Integration question: Option 1: Modify this factory private final StaticFileHandler staticFileHandler;
public DefaultConnectionHandlerFactory(HttpParser httpParser,
Logger logger,
StaticFileHandler fileHandler) {
this.httpParser = httpParser;
this.logger = logger;
this.staticFileHandler = fileHandler;
}
@Override
public Runnable create(Socket socket) {
return new ConnectionHandler(socket, httpParser, logger, staticFileHandler);
}option 2: Create a new factory public class StaticFileConnectionHandlerFactory implements ConnectionHandlerFactory {
// ... custom implementation
}Which approach aligns better with the architecture? |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package org.juv25d; | ||
|
|
||
| import org.juv25d.parser.HttpParser; | ||
|
|
||
| import java.net.Socket; | ||
| import java.util.logging.Logger; | ||
|
|
||
| public class DefaultConnectionHandlerFactory implements ConnectionHandlerFactory{ | ||
| private final HttpParser httpParser; | ||
| private final Logger logger; | ||
|
|
||
| public DefaultConnectionHandlerFactory(HttpParser httpParser, Logger logger) { | ||
| this.httpParser = httpParser; | ||
| this.logger = logger; | ||
| } | ||
|
|
||
| @Override | ||
| public Runnable create(Socket socket) { | ||
| return new ConnectionHandler(socket, httpParser, logger); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| package org.juv25d; | ||
|
|
||
| import java.io.IOException; | ||
| import java.net.ServerSocket; | ||
| import java.net.Socket; | ||
| import java.util.logging.Logger; | ||
|
|
||
| public class Server { | ||
| private static final int PORT = 3000; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: Consider making PORT configurable: private final int port;
public Server(Logger logger, ConnectionHandlerFactory factory, int port) {
this.logger = logger;
this.handlerFactory = factory;
this.port = port;
}This would allow:
But since we are only creating one server this is only a suggestion for further improvement:) |
||
| private final Logger logger; | ||
| private final ConnectionHandlerFactory handlerFactory; | ||
|
|
||
| public Server(Logger logger, ConnectionHandlerFactory handlerFactory) { | ||
| this.logger = logger; | ||
| this.handlerFactory = handlerFactory; | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| public void start() { | ||
| try (ServerSocket serverSocket = new ServerSocket(PORT, 64)) { | ||
| logger.info("Server started at port: " + serverSocket.getLocalPort()); | ||
|
|
||
| while (true) { | ||
| Socket socket = serverSocket.accept(); | ||
| Runnable handler = handlerFactory.create(socket); | ||
| Thread.ofVirtual().start(handler); | ||
| } | ||
|
|
||
| } catch (IOException e) { | ||
| throw new RuntimeException("Server error", e); | ||
| } | ||
| } | ||
|
Comment on lines
+18
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Excellent use of Virtual Threads
Question: private volatile boolean running = true;
public void stop() {
running = false;
}
while (running) {
Socket socket = serverSocket.accept();
// ...
} |
||
| } | ||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great refactoring, app.java now only handles object creation and wiring, not business logic.
Testability: Each component can now be tested independently
Flexibility: Easy to swap implementations (e.g., MockLogger for testing)
When I add
StaticFileHandler, should I pass it through theConnectionHandlerFactory, or inject it directly intoDefaultConnectionHandlerFactory? PR #36Example:
Would this be the right approach?