Skip to content

simple http server in C#81

Open
potrue wants to merge 2 commits intomainfrom
http-c
Open

simple http server in C#81
potrue wants to merge 2 commits intomainfrom
http-c

Conversation

@potrue
Copy link
Copy Markdown
Owner

@potrue potrue commented Feb 5, 2026

No description provided.

Copy link
Copy Markdown

@YUTA-Uchi YUTA-Uchi left a comment

Choose a reason for hiding this comment

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

一旦急ぎで見つけた部分をレビューしました。途中から自分が作った方にもたくさん不備がみつかってきたので私の方もプルリク上げたいと思います

break;
}

// "\r\n\r\n" (4文字) が読み込み境界を跨ぐ可能性を考慮し、3バイト戻ったところから探索する
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ここから64行目までの処理は特定のOSのための処理でしょうか?
\r\nが出てくるとWindows向けの特別な処理をやっているように見えました。(\r\nがWindowsの改行文字なので)もし特別処理であればその処理だけ関数別にしたほうがわかりやすい気がします。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

(正直書いた時は詳しく把握できていませんでしたが、)これは送られてきているリクエストからヘッダーを切り離す(空行を見つける)処理で、RFC9112で改行は\r\n(CRLF)で表すように決められているみたいなので、特にOS固有の処理ではなく、ヘッダーがここまでだというのを判断するためにOS共通で使用しているロジック、という感じです。
プログラムを書いた時には全然見られていませんでしたが、本当はこちらに書いてある"The normal procedure"に従ってリクエストを読み込むのが良さそうかもしれません。

}

if (strncmp(read_buffer, path_prefix, strlen(path_prefix)) != 0) {
respond_and_close(connection_fd, 404, "The requested URL was not found on this server\n");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

しっかり追えているか不安ですが、ここでfree(read_buffer);したほうがメモリリークがないかもです

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

あ、これは必要そうですね!メモリリークを起こしていそうです。L97にも必要だと思います。

}

if (strncmp(read_buffer + strlen(path_prefix), query_prefix, strlen(query_prefix)) != 0) {
respond_and_close(connection_fd, 400, "Failed to find query");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ここも同様です。free(read_buffer);したほうがメモリリークがないかもです

@@ -0,0 +1,8 @@
コンパイル・実行(Unix/Linux環境):
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

https://github.com/potrue/leetcode/pull/81/changes#r2781804952
もし上記の処理がWindows向けであるならば、ここも変更が必要か検討が必要かと思います

};

if (bind(socket_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
perror("bind");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

close(socket_fd);をしておいた方が良いと思います

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

これもあったほうが良さそうです。

}

if (listen(socket_fd, BACKLOG_SIZE) < 0) {
perror("listen");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

close(socket_fd);をしておいた方が良いと思います

return;
}

write(connection_fd, response, response_len);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

write が失敗したり、部分的にだけ書き込みが成功した場合に対応したい。


static char* read_request(int connection_fd) {
size_t capacity = INITIAL_READ_BUFFER_SIZE;
char* read_buffer = malloc(capacity);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

malloc が NULL を返したら?

return;
}

if (strncmp(read_buffer, path_prefix, strlen(path_prefix)) != 0) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

/calc で始まれば、他の path でも区別して動いてしまう
GET /calcium?hoge=...

return;
}

if (strncmp(read_buffer + strlen(path_prefix), query_prefix, strlen(query_prefix)) != 0) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

query 引数が第1引数だった時以外は動かない?
/calc?utm_source=github&query=1+2


char* query_start = read_buffer + strlen(path_prefix) + strlen(query_prefix);
int a, b;
if (sscanf(query_start, "%d+%d", &a, &b) != 2) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

足し算以外のケースも対応したい

@@ -0,0 +1,6 @@
#ifndef UTILS_H
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

HANDLER_H?

@@ -0,0 +1,8 @@
コンパイル・実行(Unix/Linux環境):

`gcc -o server server.c utils.c`
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

utils.c が handler.c に変わった?


動作確認:

`curl http://127.0.0.1:8080/calc\?query\=1+11` など
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

これブラウザからだとどう入力するのが正しくなりますか? (url encoding)


int connection_fd = accept(socket_fd, (struct sockaddr*)&client_addr, &client_addr_size);
if (connection_fd < 0) {
perror("accept");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

EINTR などの一時的なエラーの場合はリカバリしたい。

total_read_size += read_size;
read_buffer[total_read_size] = '\0';

if (strstr(read_buffer + str_search_offset, "\r\n\r\n")) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

データを全部読み切らずに、改行2つで早期に止めるのはどういうケースを想定をしていますか?
(keep alive?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants