Skip to content
Merged
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
60 changes: 22 additions & 38 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
name: C Build and Test
on:
workflow_dispatch:
pull_request:
push:
branches:
Expand All @@ -10,52 +11,35 @@ env:
jobs:
build-and-test:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
container:
image: koutoftimer/oduortoni-c-http-server-actions:latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.PAT_TOKEN }}
fetch-depth: 0
ref: ${{ github.head_ref || github.ref }}

- name: Cache APT packages
uses: actions/cache@v4
with:
path: /var/cache/apt/archives
key: ${{ runner.os }}-apt-${{ hashFiles('**/build-and-test.yml') }}
restore-keys: |
${{ runner.os }}-apt-

- name: Auto-format code
- name: Cache build artifacts
uses: actions/cache@v4
with:
path: |
bin/
obj/
Comment thread
oduortoni marked this conversation as resolved.
key: ${{ runner.os }}-build-${{ hashFiles('src/**', 'Makefile') }}
restore-keys: |
${{ runner.os }}-build-

- name: Install dependencies
run: |
set -x # Enable debug output

git config --global --add safe.directory $PWD
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"

# Run formatting
pre-commit run --all-files || true

# Debug: show git status
echo "=== Git Status ==="
git status
echo "=== Git Diff ==="
git diff
echo "=== Porcelain ==="
git status --porcelain

# Exit early if no changes
if [ -z "$(git status --porcelain)" ]; then
echo "✓ No formatting changes needed"
exit 0
fi

# Only set up git remote if we actually need to push
echo "Changes detected, setting up authentication..."
git remote set-url origin https://x-access-token:${{ secrets.PAT_TOKEN }}@github.com/${{ github.repository }}.git

git add -A
git commit -m "style: auto-format code with clang-format [skip ci]"
git push
echo "✓ Code formatted and pushed"
sudo apt-get update
sudo apt-get install -y gcc-14 make curl libgtest-dev pkg-config

- name: Build C code
run: |
Expand Down
20 changes: 19 additions & 1 deletion src/lib/net/net_serve.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
#include <errno.h>
#include <signal.h>

#include "header.h"
#include "utils/logging/header.h"

volatile sig_atomic_t shutdown_requested = false;

void
signal_hander([[maybe_unused]] int sig)
{
shutdown_requested = true;
}

/**
* Starts a server that listens for incoming connections on the specified host
* and port. The server will accept incoming connections and pass them to the
Expand All @@ -19,6 +30,12 @@
int
net_serve(char* host, ProtocolHandler handle_protocol, RequestContext* context)
{
struct sigaction sa = {.sa_handler = signal_hander};
// Termination signal
sigaction(SIGTERM, &sa, nullptr);
// Interrupt from keyboard
sigaction(SIGINT, &sa, nullptr);

int port;
char head[50], tail[50];

Expand All @@ -31,14 +48,15 @@ net_serve(char* host, ProtocolHandler handle_protocol, RequestContext* context)
int server_socket = net_listener(head, port);
info("Serving requests on %s\n", host);

while (1) {
while (!shutdown_requested) {
struct sockaddr_in client_addr;
socklen_t client_addrlen = sizeof(client_addr);
int client_conn =
accept(server_socket, (struct sockaddr*)&client_addr,
&client_addrlen);

if (client_conn < 0) {
if (errno == EINTR) continue;
perror("accept() failed");
close(server_socket);
exit(1);
Expand Down
9 changes: 2 additions & 7 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,8 @@ main()

http.ListenAndServe(hostname, router);

/*
* TODO: This is never reached due to infinite listener that stops on
* CTRL + C
* - Need to add a way to handle graceful shut down
*/
// info("\n\n\t << Graceful Shutdown >>\n\n");
// router_free(router);
printf("\n\n\t << Graceful Shutdown >>\n\n");
router_free(router);

return 0;
}
15 changes: 9 additions & 6 deletions tests/integration-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,18 @@ for i in {1..25}; do
fi
done

# Run Hurl tests
if [ -z "$HURL" ]; then
HURL="hurl"
fi
echo "Testing routes..."

$HURL --test --variable PORT="$PORT" tests/integration-tests.hurl
curl -s "$HOST/" | grep -q "A Minimalistic C Server" || die "Home page test failed"
echo "✓ Home page works"

[ $? -ne 0 ] && die "hurl failed"
curl -s "$HOST/nonexistent" | grep -q "404" || die "404 test failed"
echo "✓ 404 handling works"

echo "All integration tests passed"

# Check for closing connection
printf '' > /dev/tcp/127.0.0.1/9000
sleep 0.3

echo "Testing closing connection complete"
Loading