Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# C++ configuration
build --cxxopt=-std=c++17
build --host_cxxopt=-std=c++17

# Output configuration
build --verbose_failures
build --color=yes

# Test configuration
test --test_output=errors
test --test_summary=detailed
1 change: 1 addition & 0 deletions .bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7.0.0
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,8 @@ dist/
*.log
.turbo/
.cache/

# Bazel
bazel-*
.bazel-cache/
.bazelrc.user
11 changes: 11 additions & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
workspace(name = "helix_server")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

# GoogleTest
http_archive(
name = "com_google_googletest",
sha256 = "8ad598c73ad796e0d8280b082cebd82a630d73e73cd3c70057938a6501bba5d7",
strip_prefix = "googletest-1.14.0",
urls = ["https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz"],
)
1 change: 1 addition & 0 deletions _codeql_detected_source_root
1 change: 1 addition & 0 deletions packages/tcp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/
22 changes: 22 additions & 0 deletions packages/tcp/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")

# TCP Server Library
cc_library(
name = "tcp_server",
srcs = ["src/tcp_server.cc"],
hdrs = ["include/tcp_server.hpp"],
includes = ["include"],
visibility = ["//visibility:public"],
)

# TCP Server Tests
cc_test(
name = "tcp_server_test",
size = "small",
srcs = ["test/tcp_server_test.cc"],
deps = [
":tcp_server",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
],
)
48 changes: 48 additions & 0 deletions packages/tcp/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Makefile for Helix TCP Module
# Alternative build system to Bazel

CXX = g++
CXXFLAGS = -std=c++17 -Wall -Wextra -I./include
LDFLAGS =

# Directories
SRC_DIR = src
INCLUDE_DIR = include
TEST_DIR = test
BUILD_DIR = build

# Files
SOURCES = $(SRC_DIR)/tcp_server.cc
HEADERS = $(INCLUDE_DIR)/tcp_server.hpp
TEST_SOURCES = $(TEST_DIR)/manual_test.cc
OBJECTS = $(BUILD_DIR)/tcp_server.o

# Targets
.PHONY: all clean test

all: $(BUILD_DIR)/libtcp_server.a

$(BUILD_DIR):
mkdir -p $(BUILD_DIR)

$(BUILD_DIR)/tcp_server.o: $(SOURCES) $(HEADERS) | $(BUILD_DIR)
$(CXX) $(CXXFLAGS) -c $(SOURCES) -o $@

$(BUILD_DIR)/libtcp_server.a: $(OBJECTS)
ar rcs $@ $^

test: $(BUILD_DIR)/tcp_test
$(BUILD_DIR)/tcp_test

$(BUILD_DIR)/tcp_test: $(SOURCES) $(TEST_SOURCES) $(HEADERS) | $(BUILD_DIR)
$(CXX) $(CXXFLAGS) $(SOURCES) $(TEST_SOURCES) -o $@ $(LDFLAGS)

clean:
rm -rf $(BUILD_DIR)

help:
@echo "Available targets:"
@echo " all - Build the TCP server library"
@echo " test - Build and run manual tests"
@echo " clean - Remove build artifacts"
@echo " help - Show this help message"
160 changes: 160 additions & 0 deletions packages/tcp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Helix TCP Module

A C++ TCP server implementation for the Helix server framework. This module provides the foundational TCP layer that will be used to build HTTP protocol support.

## Overview

This module implements a basic TCP server in C++ with the goal of eventually supporting HTTP protocol. The library is designed to be exported as a Node.js/Bun addon.

## Structure

```
packages/tcp/
├── include/ # Header files
│ └── tcp_server.hpp
├── src/ # Implementation files
│ └── tcp_server.cc
├── test/ # Test files
│ ├── tcp_server_test.cc
│ └── manual_test.cc
├── BUILD # Bazel build configuration
├── package.json
└── README.md
```

## Features

- **TCP Server Creation**: Factory function `create_server(address, port)` to create TCP server instances
- **Address Binding**: Bind to specific IP addresses (e.g., "127.0.0.1", "0.0.0.0")
- **Port Configuration**: Configure server to listen on any valid port
- **Server Lifecycle**: Start, stop, and check server status
- **Socket Options**: Automatic SO_REUSEADDR configuration
- **Error Handling**: Comprehensive error checking for socket operations

## API

### Main Function

```cpp
std::unique_ptr<TcpServer> create_server(const std::string& address, int port);
```

Creates a new TCP server instance.

**Parameters:**
- `address`: IP address to bind to (e.g., "127.0.0.1", "0.0.0.0")
- `port`: Port number to listen on

**Returns:** Unique pointer to a new `TcpServer` instance

### TcpServer Class

```cpp
class TcpServer {
public:
// Start the server and begin listening for connections
bool start();

// Stop the server and close all connections
void stop();

// Check if the server is currently running
bool isRunning() const;

// Get the server address
const std::string& getAddress() const;

// Get the server port
int getPort() const;
};
```

## Building

### Using Bazel (Recommended)

Build the library:
```bash
bazel build //packages/tcp:tcp_server
```

Run tests:
```bash
bazel test //packages/tcp:tcp_server_test
```

### Using g++ Directly

Compile the library:
```bash
g++ -std=c++17 -c -I./include src/tcp_server.cc -o tcp_server.o
```

Compile and run manual test:
```bash
g++ -std=c++17 -I./include src/tcp_server.cc test/manual_test.cc -o tcp_test
./tcp_test
```

## Testing

The module includes comprehensive unit tests using Google Test framework:

- Server creation and configuration
- Server lifecycle (start/stop)
- Multiple server instances
- Invalid address handling
- Port binding verification
- Running state management

Run tests with:
```bash
bazel test //packages/tcp:tcp_server_test
```

## Usage Example

```cpp
#include "tcp_server.hpp"

int main() {
// Create a TCP server
auto server = helix::tcp::create_server("127.0.0.1", 8080);

// Start the server
if (server->start()) {
std::cout << "Server running on "
<< server->getAddress() << ":"
<< server->getPort() << std::endl;

// Server is now listening for connections
// ... handle connections ...

// Stop the server
server->stop();
}

return 0;
}
```

## Requirements

- C++17 or later
- POSIX-compliant system (Linux, macOS)
- Bazel for building (or g++ for manual compilation)
- Google Test for running unit tests

## Future Development

This TCP module is the foundation for HTTP protocol implementation. Planned features include:

1. Connection acceptance and management
2. HTTP request parsing
3. HTTP response generation
4. Keep-alive connection support
5. Node.js/Bun addon export

## License

MIT
84 changes: 84 additions & 0 deletions packages/tcp/include/tcp_server.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#ifndef HELIX_TCP_SERVER_HPP
#define HELIX_TCP_SERVER_HPP

#include <memory>
#include <string>

namespace helix {
namespace tcp {

// Default backlog size for listen() call
constexpr int DEFAULT_BACKLOG = 10;

/**
* Configuration for creating a TCP server
*/
struct ServerConfig {
std::string address;
int port;

ServerConfig(const std::string& addr, int p)
: address(addr), port(p) {}
};

/**
* TCP Server class
*/
class TcpServer {
public:
TcpServer(const ServerConfig& config);
~TcpServer();

// Delete copy constructor and assignment operator
TcpServer(const TcpServer&) = delete;
TcpServer& operator=(const TcpServer&) = delete;

/**
* Start the server and begin listening for connections
* @return true if server started successfully, false otherwise
*/
bool start();

/**
* Stop the server and close all connections
*/
void stop();

/**
* Check if the server is currently running
* @return true if server is running, false otherwise
*/
bool isRunning() const;

/**
* Get the server address
* @return The IP address the server is configured to bind to
*/
const std::string& getAddress() const { return config_.address; }

/**
* Get the server port
* @return The port number the server is configured to listen on
*/
int getPort() const { return config_.port; }

private:
ServerConfig config_;
int socket_fd_;
bool is_running_;
};

/**
* Factory function to create a TCP server
* This will be the main exported function for the addon
*
* @param address The IP address to bind to (e.g., "127.0.0.1", "0.0.0.0")
* @param port The port number to listen on
* @return Unique pointer to a new TcpServer instance
*/
std::unique_ptr<TcpServer> create_server(const std::string& address, int port);

} // namespace tcp
} // namespace helix

#endif // HELIX_TCP_SERVER_HPP
14 changes: 10 additions & 4 deletions packages/tcp/package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
{
"type": "module",
"name": "@helix-server/tcp",
"version": "0.1.0",
"description": "TCP server implementation for Helix server framework",
"main": "src/tcp_server.cc",
"scripts": {
"build": "echo \"Building tcp package...\"",
"publish": "echo \"Publishing tcp package...\"",
"test": "echo \"Running tests for tcp package...\""
}
"build": "bazel build //packages/tcp:tcp_server",
"test": "bazel test //packages/tcp:tcp_server_test",
"test:manual": "g++ -std=c++17 -I./include src/tcp_server.cc test/manual_test.cc -o /tmp/tcp_test && /tmp/tcp_test",
"clean": "bazel clean"
},
"keywords": ["tcp", "server", "helix", "c++", "networking"],
"license": "MIT"
}
Loading