
์ด๋ฒ ํฌ๋ํํค ์ ๊ธ 8์ฃผ์ฐจ์์ web proxy lab ๊ณผ์ ๋ฅผ ์ํํ๋ฉด์ C์ธ์ด๋ก HTTP ์์ฒญ๊ณผ ์๋ต์ ํ์ฑํด์ผ ํ์ต๋๋ค. ๋ค๋ฅธ ์ธ์ด์์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ ์ค์ด๋ฉด ๋๋ ์์ ๋ค์ด C์์๋ ์ ์ด๋ฆฌ ์ด๋ ต๊ณ , ๋ฒ๊ทธ๋ ์ ์ด๋ฆฌ ์์ฃผ ๋ํ๋๋์ง ์ ์คํ ๊นจ๋ฌ์์ต๋๋ค. ์๋ง ๋ง์ ๋ถ๋ค์ด ๋น์ทํ ๊ฒฝํ์ ํ์ จ๊ฑฐ๋, ์์ผ๋ก ๊ฒช๊ฒ ๋์๋ฆฌ๋ผ ์๊ฐํฉ๋๋ค.
๊ทธ๋์ ์ค๋์ C์ธ์ด์์์ ํ์ฑ ์์ ์ด ์ ์ ๋ ๊น๋ค๋ก์ด์ง, ๊ทธ๋ฆฌ๊ณ ์ด ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํค์ณ๋๊ฐ ์ ์์์ง์ ๋ํ ์ ๊ฒฝํ๊ณผ ํ์ ๊ณต์ ํ๊ณ ์ ํฉ๋๋ค.
C์ธ์ด ํ์ฑ, ์ ์ด๋ ๊ฒ ์ด๋ ค์ด ๊ฑธ๊น์?
- '๋งจ์์ผ๋ก ์ ๋ฒฝ ํ๊ธฐ' - ๋ฎ์ ์์ค์ ๋ฌธ์์ด ์ฒ๋ฆฌ: C๋ ๋ณธ์ง์ ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ์ ์ง์ ๊ณต๊ฐ์ ๋ด๊ณ , ๊ทธ ๊ณต๊ฐ์ ์ฐธ์กฐ, ์ฐ์ฐ, ์ ์ฅํ๋ ๊ฒ์ด ์ ๋ถ์ ๋๋ค. ๋ฌผ๋ก ์ง์ ํ๋ค๋ ๊ทธ ์์ฒด๊ฐ ๊ฐ๋ ฅํ์ง๋ง, ์ด์ธ์ ๊ฒ๋ค๊น์ง ์ง์ ํด์ผ ํ๋ค๋ ์ ์ด ๋ฌธ์ ์ ๋๋ค. Python์ split(), strip(), Java์ String.split() ๊ฐ์ ๊ณ ์์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ/ํจ์๋ ์์ต๋๋ค. ๋ง์น ๋งจ์์ผ๋ก ์ ๋ฒฝ์ ํ๋ ๋๋์ด์ง์.
- ์๊พธ ์ํ์ง๋ Null ๋ฌธ์: C ๋ฌธ์์ด์ ๋์๋ ํญ์ Null ๋ฌธ์(`\0`)๊ฐ ๋ถ์ด์ผ๋ง ํฉ๋๋ค. ํ์ฑ ๊ณผ์ ์์ ์ด๋ฅผ ์ ๋๋ก ์ฒ๋ฆฌํ์ง ์์ผ๋ฉด ๋ฌธ์์ด์ ๋์ ์ธ์ํ์ง ๋ชปํด segmentation fault๊น์ง ์ผ๊ธฐํฉ๋๋ค. strncpy ๊ฐ์ ํจ์๋ Null ๋ฌธ์๋ฅผ ๋ณด์ฅํ์ง ์์ ํนํ ์ฃผ์ํด์ผ ํฉ๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ & ์ค๋ฅ ์ฒ๋ฆฌ: ๋ฌธ์์ด์ ์ ์ฅํ ๋ฒํผ์ ํฌ๊ธฐ๋ ์ ๊ฒฝ ์จ์ผ ํฉ๋๋ค. ํ์ฑ ๊ฒฐ๊ณผ๊ฐ ๋ฒํผ ํฌ๊ธฐ๋ฅผ ๋์ด์๋ฉด ๋ฒํผ ์ค๋ฒํ๋ก๊ฐ ๋ฐ์ํ๊ณ , ์ด๋ ์ค๋ฅ๋ ์ทจ์ฝ์ ์ผ๋ก ์ด์ด์ง๋๋ค. C๋ก ์ง ํ๋ก๊ทธ๋จ์๋ ๊ด๋ฆฌ๋ ๊ฒ ์์ต๋๋ค. ๊ทธ์ ๋๋ค๊ฐ ๊ท์น์ ์ด๊ธฐ๋ฉด OS์ ์ํด ์ข ๋ฃ๋นํ ๋ฟ์ ๋๋ค... OS๊ฐ ์๋ค๋ฉด์.
ํ๋ํ C ํ์ฑ, ๊ทธ๋๋ ๊ธธ์ ์๋ค
์ด๋ฐ ์ด๋ ค์์๋ ๋ถ๊ตฌํ๊ณ , ๋ช ๊ฐ์ง ํต์ฌ ์ ๋ต๊ณผ ์ ์ฉํ ๋๊ตฌ๋ค์ด ์์ผ๋, ํ๋ฒ ๊ณ ๋ คํด ๋ณผ๋งํ๊ฒ ์ต๋๋ค.
- ํ์ฑ ๋์ ๋ช ํํ ์ดํด: ๊ฐ์ฅ ๋จผ์ ํ์ฑํ ๋ฐ์ดํฐ์ ํ์์ ์๋ฒฝํ๊ฒ ์ดํดํด์ผ ํฉ๋๋ค. HTTP ๋ฉ์์ง๋ผ๋ฉด RFC ๋ฌธ์๋ฅผ, ํน์ ํ์ผ ํ์์ด๋ผ๋ฉด ๊ทธ ๋ช ์ธ๋ฅผ ์์งํด์ผ ํฉ๋๋ค. ์ด๋ค ๊ตฌ๋ถ์(delimiter)๋ฅผ ์ฌ์ฉํ๋์ง, ๊ฐ ํ๋์ ์ต๋ ๊ธธ์ด๋ ์ผ๋ง์ธ์ง, ์ด๋ค ์์๋ก ๋ํ๋๋์ง ๋ฑ์ ํ์ ํ๋ ๊ฒ์ด ์ฒซ๊ฑธ์์ ๋๋ค.
- ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํ์ฉ: C ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์๊ฐ๋ณด๋ค (๋ค, ์ด๋๊น์ง๋ '์๊ฐ๋ณด๋ค') ์ ์ฉํ ํ์ฑ ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- string.h ๊ณ์ด:
- strstr(const char *haystack, const char *needle): ๋ฌธ์์ด ๋ด์์ ํน์ ๋ถ๋ถ ๋ฌธ์์ด(needle)์ ์ฐพ์ต๋๋ค. HTTP ํค๋์์ ํน์ ํ๋๋ช ("Host:", "Content-Length:")์ ์ฐพ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
- strchr(const char *s, int c) / strrchr(const char *s, int c): ๋ฌธ์์ด์์ ํน์ ๋ฌธ์(c)๋ฅผ ์์์๋ถํฐ/๋ค์์๋ถํฐ ์ฐพ์ต๋๋ค. ๊ตฌ๋ถ์๋ฅผ ์ฐพ์ ๋ ์ฌ์ฉํฉ๋๋ค.
- strncmp(const char *s1, const char *s2, size_t n): ๋ ๋ฌธ์์ด์ n๋ฐ์ดํธ๋งํผ ๋น๊ตํฉ๋๋ค. ํน์ ํค์๋๋ก ์์ํ๋์ง ํ์ธํ ๋ ์์ ํ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- strtok_r(char *str, const char *delim, char **saveptr): ๋ฌธ์์ด์ ๊ตฌ๋ถ์(delim) ๊ธฐ์ค์ผ๋ก ํ ํฐํํฉ๋๋ค. ์๋ณธ ๋ฌธ์์ด์ ๋ณ๊ฒฝํ๊ณ , ์ค๋ ๋ ํ๊ฒฝ์์๋ strtok ๋์ strtok_r์ ์ฌ์ฉํด์ผ ์์ ํฉ๋๋ค.
- memcpy(void *dest, const void *src, size_t n) / strncpy(char *dest, const char *src, size_t n): ํ์ฑ๋ ๋ถ๋ถ์ ๋ค๋ฅธ ๋ฒํผ๋ก ๋ณต์ฌํ ๋ ์ฌ์ฉํฉ๋๋ค. strncpy๋ Null ์ข ๋ฃ๋ฅผ ๋ณด์ฅํ์ง ์์ผ๋ฏ๋ก, ์๋์ผ๋ก Null ๋ฌธ์๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ dest[n-1] = '\0' ์ฒ๋ฆฌ๋ฅผ ํด์ค์ผ ํ ๋๊ฐ ๋ง์ต๋๋ค.
- stdio.h ๊ณ์ด:
- sscanf(const char *str, const char *format, ...): ๋ฌธ์์ด์์ ํ์ํ๋ ์ ๋ ฅ์ ์ฝ์ด์ต๋๋ค. "Key: Value" ํํ์์ ์ ์ ๊ฐ์ ์ฝ๊ฑฐ๋, ํน์ ํจํด์ ๋ฌธ์์ด์ ์ถ์ถํ ๋ ์ ์ฉํ์ง๋ง, ๋ฒํผ ์ค๋ฒํ๋ก์ ์ฃผ์ํด์ผ ํฉ๋๋ค. (์: %s ๋์ %10s์ฒ๋ผ ๋๋น ์ง์ )
- stdlib.h ๊ณ์ด:
- strtol(const char *nptr, char **endptr, int base) / strtod(const char *nptr, char **endptr): ๋ฌธ์์ด์ ์ ์(long)๋ ์ค์(double)๋ก ๋ณํํฉ๋๋ค. atoi, atof๋ณด๋ค ์ค๋ฅ ๊ฒ์ฌ(๋ณํ ๋ถ๊ฐ๋ฅํ ๋ฌธ์, ์ค๋ฒํ๋ก ๋ฑ)์ ์ฉ์ดํ์ฌ ์์ ํฉ๋๋ค. endptr์ ํตํด ๋ณํ์ด ๋๋ ์์น๋ฅผ ์ ์ ์์ต๋๋ค.
- string.h ๊ณ์ด:
- ํฌ์ธํฐ์ ๋ฐ๋ณต๋ฌธ์ผ๋ก ์ง์ (character-by-character) ํ์ฑ: ๋ณต์กํ ๊ท์น์ด๋ ์ํ(state)๋ฅผ ๊ฐ์ ธ์ผ ํ๋ ํ์ฑ์ ๊ฒฝ์ฐ, ์ง์ ํฌ์ธํฐ๋ฅผ ์ด๋์ํค๋ฉฐ ๋ฌธ์ ๋จ์๋ก ๊ฒ์ฌํ๋ ๊ฒ์ด ํจ๊ณผ์ ์
๋๋ค.
- HTTP ํค๋๋ฅผ ํ ์ค์ฉ ์ฝ๊ฑฐ๋(
\r\n
์ฐพ๊ธฐ), ํน์ ๊ตฌ๋ถ์ ์ฌ์ด์ ๊ฐ์ ์ถ์ถํ ๋ ์ ์ฉํฉ๋๋ค. - ์ํ ๋ณ์๋ฅผ ๋์ด ํ์ฌ ํ์ฑ ์ํ(์: ํค๋ฅผ ์ฝ๋ ์ค, ๊ฐ์ ์ฝ๋ ์ค)๋ฅผ ๊ด๋ฆฌํ๋ฉด ๋ณต์กํ ๋ก์ง๋ ๊ตฌํํ ์ ์์ต๋๋ค.
// ์์: ':' ๋ฌธ์๋ฅผ ์ฐพ์ key์ value๋ฅผ ๊ตฌ๋ถํ๋ ๋จ์ ๋ก์ง char buffer[MAXLINE]; // ํ์ฑํ ํ ์ค์ด ๋ด๊ฒจ์๋ค๊ณ ๊ฐ์ char *key_ptr = buffer; char *value_ptr = NULL; char *colon_ptr = strchr(buffer, ':'); if (colon_ptr != NULL) { *colon_ptr = '\0'; // key ๋ถ๋ถ์ Null๋ก ์ข ๋ฃ value_ptr = colon_ptr + 1; // ':' ๋ค์๋ถํฐ value ์์ // value ์ ๊ณต๋ฐฑ ์ ๊ฑฐ (์ ํ์ ) while (*value_ptr == ' ' || *value_ptr == '\t') { value_ptr++; } // ์ด์ key_ptr๊ณผ value_ptr์ ์ฌ์ฉ printf("Key: %s, Value: %s\n", key_ptr, value_ptr); }
- HTTP ํค๋๋ฅผ ํ ์ค์ฉ ์ฝ๊ฑฐ๋(
- ๋ฒํผ ๊ด๋ฆฌ, ์์ ๋ ์์ :
- ํญ์ ๋ฒํผ์ ํฌ๊ธฐ๋ฅผ ์ธ์งํ๊ณ , ์ฝ๊ฑฐ๋ ์ธ ๋ฐ์ดํฐ๊ฐ ๋ฒํผ๋ฅผ ๋์ง ์๋๋ก ๊ฒฝ๊ณ ๊ฒ์ฌ๋ฅผ ์ฒ ์ ํ ํฉ๋๋ค. ๊ฐ๋ น sprintf ๋์ snprintf๋ฅผ ์ฌ์ฉํ์ฌ ์ถ๋ ฅ ๊ธธ์ด๋ฅผ ์ ํํฉ๋๋ค.
- ํ์ฑ๋ ๋ฌธ์์ด์ ์ ์ฅํ ๋๋ ํญ์ Null ๋ฌธ์๋ฅผ ์ํ ๊ณต๊ฐ์ ์ถ๊ฐ๋ก ํ๋ณดํ๊ณ , ๋ณต์ฌ ํ Null ๋ฌธ์๋ฅผ ๋ช ์์ ์ผ๋ก ๋ฃ์ด์ฃผ๋ ์ต๊ด์ ๋ค์ ๋๋ค. ๊ฐ๋ น "CAT"๋ผ๋ ๋ฌธ์์ด์ ๋ด๊ธฐ ์ํ ํฌ๊ธฐ๋, 3์ด ์๋๋ผ 4์ ๋๋ค. CAT ๋์ `\0`์ด ๋ค์ด๊ฐ๋๊น์.
- ๊ผผ๊ผผํ ๋๋ฒ๊น
& ๋ก๊น
:
- ํจ์๊ฐ ์คํจํ ์ ์๋ ๋ชจ๋ ์ง์ ์์ ๋ฐํ ๊ฐ์ ํ์ธํ๊ณ , ์ค๋ฅ ์ํฉ์ ๋์ฒํฉ๋๋ค. (์: strstr๊ฐ NULL์ ๋ฐํํ๋ ๊ฒฝ์ฐ)
- errno๋ฅผ ํ์ธํ์ฌ ์์คํ ์ฝ ์ค๋ฅ์ ์์ธ์ ํ์ ํฉ๋๋ค.
- gcc๋ก ์ปดํ์ผ ์ -g๋ฅผ, ๊ทธ๋ฆฌ๊ณ gdb๋ก ๋๋ฒ๊ทธํฉ๋๋ค. gdb์๋ backtrace, frame <๋ฒํธ>, print <๋ณ์> ๋ฑ ์๊ฐ๋ณด๋ค (๋ค, ์ญ์๋ ์ด๋๊น์ง๋ '์๊ฐ๋ณด๋ค') ๋จ์๊ฐ ๋์ด์ค ๋งํ ๊ธฐ๋ฅ๋ค์ด ์์ต๋๋ค.
gcc -g -o my_program my_program.c // -g ์ต์
์ ํตํด ๋๋ฒ๊ทธ์ฉ ์ ๋ณด ์์ฑ
gdb ./my_program
(gdb) run # ํ๋ก๊ทธ๋จ ์คํ
... (์ธ๊ทธํดํธ ๋ฐ์) ...
(gdb) backtrace # ๋๋ bt. ์ฝ ์คํ์ ๋ณด์ฌ์ฃผ์ด ์ด๋์ ์ค๋ฅ๊ฐ ๋ฌ๋์ง ํ์ธ
(gdb) frame <๋ฒํธ> # ํน์ ์คํ ํ๋ ์์ผ๋ก ์ด๋
(gdb) print <๋ณ์> # ๋ณ์ ๊ฐ ํ์ธ
(gdb) x/ <ํฌ๋งท> <์ฃผ์> # ํน์ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์์ ๋ด์ฉ ํ์ธ (์: x/10wx 0x...)
C์ธ์ด์์ ์จ๋ณด๋ ์ ๊ทํํ์
GitHub - PCRE2Project/pcre2: PCRE2 development is based here.
PCRE2 development is based here. Contribute to PCRE2Project/pcre2 development by creating an account on GitHub.
github.com
C์์๋ ์ ๊ทํํ์์ ํ์ฉํ ์ ์๋ค๋ฉด ์ด๋ง์ด๋งํ ๋์์ด ๋ ๊ฒ์ ๋๋ค. ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์๋ค๋ ๊ฒ ๋ฌธ์ ์ด์ง์. ์ด๋ด ๋ ์ฌ์ฉํ ์ ์๋ ๊ฒ์ด ๋ฐ๋ก PCRE2(Perl Compatible Regular Expressions version 2)์ ๋๋ค. ์ ธ์ Ubuntu ๊ธฐ์ค์ผ๋ก ์๋์ ๊ฐ์ด ์ ๋ ฅํ์ฌ PCRE2 ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํฉ๋๋ค.
sudo apt install libpcre2-dev
์ปดํ์ผํ ๋๋ ์๋์ ๊ฐ์ด -lpcre2-8
์ต์
์ ๋ถ์
๋๋ค.
gcc ./regex1.c -o regex1 -lpcre2-8
์ฌ์ฉ๋๋ ํค๋ ํ์ผ ๋ฐ ์์ ์ฝ๋์ ๋ํด์๋, ์๋ ์ค์ ์์ 2๋ฅผ ์ฐธ๊ณ ํ์ฌ ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.
์ค์ ์์ 1: ๋ฒ์ฉ ๋ฌธ์์ด ์ซ์ ํ์ฑ
์๋ ์์ ๋ "12345", "3.14" ๊ฐ์ char[]์ ์ ๋ ฅ๋ฐ์ ์ด๋ฅผ int ๋๋ double๋ก ๋ณํํฉ๋๋ค.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <float.h>
/**
* ๋ฌธ์์ด์ ์ ์(int)๋ก ๋ณํ
* ์คํจ ์ 0 ๋ฐํ + ์ค๋ฅ ๋ฉ์์ง ์ถ๋ ฅ
*/
int parse_int(const char *str, int *result) {
char *endptr;
long val;
errno = 0; // ์ค๋ฅ ํ๋๊ทธ ์ด๊ธฐํ
val = strtol(str, &endptr, 10);
// ์ค๋ฅ ์ฒดํฌ
if (errno == ERANGE || val < INT_MIN || val > INT_MAX) {
fprintf(stderr, "parse_int: out of range\n");
return 0;
}
if (endptr == str || *endptr != '\0') {
fprintf(stderr, "parse_int: invalid input '%s'\n", str);
return 0;
}
*result = (int)val;
return 1;
}
/**
* ๋ฌธ์์ด์ ์ค์(double)๋ก ๋ณํ
* ์คํจ ์ 0 ๋ฐํ + ์ค๋ฅ ๋ฉ์์ง ์ถ๋ ฅ
*/
int parse_double(const char *str, double *result) {
char *endptr;
double val;
errno = 0;
val = strtod(str, &endptr);
if (errno == ERANGE || val < -DBL_MAX || val > DBL_MAX) {
fprintf(stderr, "parse_double: out of range\n");
return 0;
}
if (endptr == str || *endptr != '\0') {
fprintf(stderr, "parse_double: invalid input '%s'\n", str);
return 0;
}
*result = val;
return 1;
}
int main() {
const char *int_str = "12345";
const char *double_str = "3.14159";
const char *bad_str = "42abc";
int i;
double d;
if (parse_int(int_str, &i))
printf("Parsed int: %d\n", i);
if (parse_double(double_str, &d))
printf("Parsed double: %f\n", d);
// ์คํจ ์์
parse_int(bad_str, &i);
parse_double(bad_str, &d);
return 0;
}
์ ์์๋ ๊ธฐ๋ณธ์ ์ธ ์์ด๋์ด๋ง ๋ค๋ฃจ๋ฉฐ, ์ค์ HTTP ํ์๋ผ๋ฉด \r\n
์ฒ๋ฆฌ, ๋์๋ฌธ์ ๋ฌด์ ๋น๊ต (ํค๋ ํ๋๋ช
), ๊ฐ์ ์ธ์ฝ๋ฉ ์ฒ๋ฆฌ ๋ฑ ์์ RFC๋๋ก ๊ตฌํํ๋ ์์ค์ด ๋์ด์ผ ํ ๊ฒ์
๋๋ค.
์ค์ ์์ 2: HTTP ํค๋ ํ์ฑ (PCRE2 ํ์ฉ)
PCRE2๋ ํนํ ๋ณต์กํ ๋ฌธ์์ด ํ์ฑ์ด ์๊ตฌ๋ ๋ ๊ทธ ๋น์ ๋ฐํฉ๋๋ค. ์๋๋ GET http://google.com/webhp?hl=ko HTTP/1.1
๊ฐ์ HTTP request ํ ์ค์ PCRE2๋ก ํ์ฑํ๋ ์์ ์
๋๋ค.
- HTTP Method →
GET
- Origin hostname →
google.com
- Port (์์ผ๋ฉด default
80
) →80
- Path →
/webhp?hl=ko
- HTTP Version →
HTTP/1.1
์ด๋ ํ์ํ ์ ๊ทํํ์์ ^([A-Z]+)\s+http://([^/:]+)(?::(\d+))?(/[^ ]*)\s+(HTTP/\d(?:\.\d)?)
์
๋๋ค.
์ ๊ทํํ์ ๊ทธ๋ฃน ๋ฒํธ | ์ค๋ช | ์์ ๊ฐ |
1 ([A-Z]+) | HTTP Method | GET |
2 ([^\/:]+) | Hostname | google.com |
3 (\d+) | Port | - (→ ์ ๊ทํํ์ ํ์ฑ ํ C ์ฝ๋๋ก 80์ ์ง์ ) |
4 (/[^ ]*) | Path | /webhp?hl=ko |
5 (HTTP/\d(?:\.\d)?) | HTTP Version | HTTP/1.1 |
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
PCRE2_SPTR pattern = (PCRE2_SPTR)"^([A-Z]+)\\s+http://([^/:]+)(?::(\\d+))?(/[^ ]*)\\s+(HTTP/\\d\\.\\d)";
PCRE2_SPTR subject = (PCRE2_SPTR)"GET http://google.com/webhp?hl=ko HTTP/1.1";
int errornumber;
PCRE2_SIZE erroroffset;
pcre2_code *re = pcre2_compile(
pattern, PCRE2_ZERO_TERMINATED, 0,
&errornumber, &erroroffset, NULL);
if (re == NULL) {
PCRE2_UCHAR buffer[256];
pcre2_get_error_message(errornumber, buffer, sizeof(buffer));
printf("Regex compile error at offset %d: %s\n", (int)erroroffset, buffer);
return 1;
}
pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(re, NULL);
int rc = pcre2_match(
re, subject, strlen((char *)subject),
0, 0, match_data, NULL);
if (rc < 0) {
printf("Match failed\n");
pcre2_match_data_free(match_data);
pcre2_code_free(re);
return 1;
}
PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
char buffer[256];
const char *labels[] = {"Method", "Host", "Port", "Path", "Version"};
for (int i = 1; i <= 5; i++) {
PCRE2_SIZE start = ovector[2 * i];
PCRE2_SIZE end = ovector[2 * i + 1];
size_t len = end - start;
strncpy(buffer, (char *)subject + start, len);
buffer[len] = '\0';
printf("%s: %s\n", labels[i - 1], buffer);
}
// ์์ธ์ฒ๋ฆฌ: ํฌํธ๊ฐ ์์ผ๋ฉด 80์ผ๋ก ๊ธฐ๋ณธ๊ฐ ์ฒ๋ฆฌ
if (ovector[6] == ovector[7]) {
printf("Port (default): 80\n");
}
pcre2_match_data_free(match_data);
pcre2_code_free(re);
return 0;
}
์คํ ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ์ต๋๋ค.
์ ๊ทํํ์์ ํ์ฉํ ๋ ์ถ์ฒ ๋๋ฆฌ๋ ์น์ฌ์ดํธ์ ๋๋ค. ์ฌ๊ธฐ์๋ ์ ๊ทํํ์์ ํ ์คํธํ ์ ์์ต๋๋ค. https://regex101.com/
regex101: build, test, and debug regex
Regular expression tester with syntax highlighting, explanation, cheat sheet for PHP/PCRE, Python, GO, JavaScript, Java, C#/.NET, Rust.
regex101.com
์ฐธ๊ณ ๋ก regex101.com๊ณผ C์์ ์ด์ค์ผ์ดํ ๋ฌธ์๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ ๊ฑฐ๊พธ๋ก์ด๋, ์ด๋ฅผ ์๊ณ ์ฌ์ฉํ์๋ฉด ์ข๊ฒ ์ต๋๋ค.
๋ง์น๋ฉฐ
ํ์ฑ ์์ฒด๋ ์ฝ์ง ์์ง๋ง, ๊ทธ๊ฑธ C๋ก ํ๋ค๋ ๊ฒ์ ์ฌ๋ฌ๋ชจ๋ก ๋ํดํ ์ผ์ ๋๋ค. ํ์ง๋ง ์ด ๋ํ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ, ํฌ์ธํฐ, ๋ฌธ์์ด ์ฒ๋ฆฌ์ ํจ๊ป ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊น์ง ์ฌ์ฉํด๋ณด๋ ์๋ก์ด ๊ณ๊ธฐ๊ฐ ๋ ๊ฒ์ ๋๋ค. ์ ์ ๊ฒฝํ์ด ์ฌ๋ฌ๋ถ์๊ฒ๋ ์กฐ๊ธ์ด๋๋ง ๋์์ด ๋์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
'IT > ๊ธฐํ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์น ํ๋ก์ ๋ฉ: ๋ค๋ ์บ์์ ํด์ ๋ผ์น๊ธฐ (djb2 ํด์ + ์ด์ค ์ฐ๊ฒฐ ๋ฆฌ์คํธ) (0) | 2025.05.06 |
---|---|
Pintos ์๋ฃ ์ทจํฉ (0) | 2025.04.22 |
WSLg Ubuntu 24.04.1 LTS์์ GUI ์ฐฝ์ด ๋จ์ง ์๊ฑฐ๋ ์ฅ์๊ฐ ๊ธฐ๋ค๋ ค์ผ๋ง ๋ฐ ๋ (0) | 2025.04.16 |
์๋์ฐ 11 "์ฐฝ์ ๋๋๊ทธํ ๋๋ง๋ค ์์ ๋ญ ๋จ๋ ๊ทธ๊ฑฐ" ๋นํ์ฑํํ๊ธฐ (0) | 2025.04.04 |
์๋์ฐ 11 ๋ ธํธ๋ถ ์ฝํ์ผ๋ฟ ํค ๋นํ์ฑํ/๋์ฒดํ๊ธฐ (0) | 2025.02.19 |
์คํฐ๋ ๋ ธํธ 12์ 13์ผ: VIM (1) | 2023.12.17 |
Flatpak ๊ธฐ๋ฐ Bottles์ ์คํ ์์ (0) | 2022.07.17 |
์๋ ํ์ธ์.
ํฌ์คํ ์ด ์ข์๋ค๋ฉด "์ข์์โค๏ธ" ๋๋ "๊ตฌ๋ ๐๐ป" ํด์ฃผ์ธ์!