#프로젝트 구조
Cheolsu Proxy는 Rust 기반의 모노레포 구조로 구성되어 있으며, Tauri를 사용한 데스크톱 애플리케이션입니다.
#전체 구조
cheolsu-proxy/
├── Cargo.toml # 워크스페이스 루트 설정
├── Cargo.lock # 의존성 잠금 파일
├── README.md # 프로젝트 소개
├── CONTRIBUTING.md # 기여 가이드 (영어)
├── CONTRIBUTING_KO.md # 기여 가이드 (한국어)
├── document/ # 문서 (기존)
├── assets/ # 프로젝트 에셋
├── desktop/ # 프론트엔드 (React + TypeScript)
├── proxyapi/ # 레거시 프록시 API
├── proxyapi_models/ # 레거시 모델
├── proxyapi_v2/ # 새로운 프록시 API
├── proxyapi_v2_models/ # 새로운 모델
└── proxy_v2_models/ # 공통 모델#워크스페이스 구조
#루트 Cargo.toml
[workspace]
members = [
"proxyapi",
"proxyapi_v2",
"proxyapi_models",
"desktop/src-tauri",
]
[workspace.dependencies]
# 공통 의존성 정의#워크스페이스 외부 크레이트
proxy_v2_models는 워크스페이스 멤버는 아니지만, 다른 워크스페이스 멤버들이 의존성으로 참조하는 별도의 크레이트입니다.
#주요 모듈
- har.rs: HAR 1.2 형식 변환 모듈 (
build_har(),build_har_json()) - request.rs / response.rs: HTTP 요청/응답 모델
- data_type.rs: 데이터 타입 분류
- file_storage.rs: Body 파일 저장 관리
#백엔드 구조
#1. proxyapi_v2/ (메인 프록시 엔진)
proxyapi_v2/
├── Cargo.toml # 패키지 설정
├── src/
│ ├── lib.rs # 라이브러리 진입점
│ ├── error.rs # 에러 타입 정의
│ ├── body.rs # HTTP 바디 처리
│ ├── decoder.rs # HTTP 디코더
│ ├── rewind.rs # 스트림 리와인드
│ ├── noop.rs # No-op 핸들러
│ ├── tls_version_detector.rs # TLS 버전 감지
│ ├── hybrid_tls_handler.rs # 하이브리드 TLS 핸들러
│ └── tunnel_event.rs # 터널 이벤트 처리
│ ├── certificate_authority/ # CA 인증서 관리
│ │ ├── mod.rs
│ │ ├── rcgen_authority.rs # rcgen 기반 CA
│ │ ├── openssl_authority.rs # OpenSSL 기반 CA
│ │ ├── cheolsu-proxy.cnf # OpenSSL 설정 파일
│ │ └── cheolsu-proxy.srl # OpenSSL 직렬 번호 파일
│ └── proxy/ # 프록시 핵심 로직
│ ├── mod.rs
│ ├── builder.rs # 프록시 빌더
│ └── internal.rs # 내부 프록시 로직
├── examples/ # 사용 예제
│ ├── improved_rustls_proxy.rs
│ ├── log.rs
│ ├── noop.rs
│ ├── openssl.rs
│ └── tls_hybrid_test.rs
├── tests/ # 통합 테스트
│ ├── common/
│ │ └── mod.rs
│ ├── integration_error_handling_tests.rs
│ ├── logging_handler_error_tests.rs
│ ├── openssl_ca.rs
│ ├── rcgen_ca.rs
│ └── websocket.rs
└── benches/ # 벤치마크
├── certificate_authorities.rs
├── decoder.rs
└── proxy.rs#2. certificate_authority/ (CA 관리)
#모듈 구조
// mod.rs
pub trait CertificateAuthority {
fn generate_certificate(&self, domain: &str) -> Result<Certificate, Error>;
fn gen_pkcs12_identity(&self, domain: &str) -> Result<Identity, Error>;
}
pub struct RcgenAuthority { /* ... */ }
pub struct OpensslAuthority { /* ... */ }#주요 기능
- 동적 인증서 생성: 도메인별 인증서 자동 생성
- PKCS12 지원: native-tls용 PKCS12 인증서 생성
- 크로스 플랫폼: macOS, Windows 지원
#3. proxy/ (프록시 핵심)
#Builder 패턴
// builder.rs
pub struct ProxyBuilder {
listen_addr: SocketAddr,
ca: Box<dyn CertificateAuthority>,
tls_handler: Box<dyn TlsHandler>,
}
impl ProxyBuilder {
pub fn new() -> Self { /* ... */ }
pub fn listen_addr(mut self, addr: SocketAddr) -> Self { /* ... */ }
pub fn certificate_authority(mut self, ca: Box<dyn CertificateAuthority>) -> Self { /* ... */ }
pub fn build(self) -> Result<Proxy, Error> { /* ... */ }
}#내부 로직
// internal.rs
pub struct Proxy {
listener: TcpListener,
ca: Box<dyn CertificateAuthority>,
tls_handler: Box<dyn TlsHandler>,
}
impl Proxy {
pub async fn run(&self) -> Result<(), Error> { /* ... */ }
async fn handle_connection(&self, stream: TcpStream) -> Result<(), Error> { /* ... */ }
async fn handle_http(&self, stream: TcpStream) -> Result<(), Error> { /* ... */ }
async fn handle_https(&self, stream: TcpStream) -> Result<(), Error> { /* ... */ }
}#프론트엔드 구조 (desktop/)
#FSD (Feature-Sliced Design) 아키텍처
desktop/src/
├── main.tsx # 애플리케이션 진입점
├── main.css # 글로벌 스타일
├── app/ # 애플리케이션 레이어
│ ├── App.tsx # 루트 컴포넌트
│ ├── layouts/ # 레이아웃 컴포넌트
│ └── providers/ # 컨텍스트 프로바이더
│ ├── index.ts
│ ├── router-provider.tsx
│ └── use-theme-provider.ts
├── pages/ # 페이지 레이어
│ ├── network-dashboard/ # 네트워크 대시보드
│ │ ├── hooks/
│ │ │ ├── index.ts
│ │ │ ├── use-proxy-event-control.ts
│ │ │ ├── use-theme-provider.ts
│ │ │ ├── use-transaction-filters.ts
│ │ │ └── use-transactions.ts
│ │ ├── index.ts
│ │ ├── lib/
│ │ │ ├── index.ts
│ │ │ └── utils.ts
│ │ └── ui/
│ │ ├── index.ts
│ │ └── network-dashboard.tsx
│ └── sessions/ # 세션 관리
│ ├── index.ts
│ └── ui/
│ └── sessions-page.tsx
├── widgets/ # 위젯 레이어
│ ├── network-table/ # 네트워크 테이블
│ │ ├── hooks/
│ │ │ ├── index.ts
│ │ │ └── use-table-data.ts
│ │ ├── index.ts
│ │ ├── lib/
│ │ │ ├── index.ts
│ │ │ └── utils.ts
│ │ ├── model/
│ │ │ ├── consts.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── ui/
│ │ ├── cells/
│ │ │ ├── action-cell.tsx
│ │ │ ├── index.ts
│ │ │ ├── method-cell.tsx
│ │ │ ├── path-cell.tsx
│ │ │ ├── size-cell.tsx
│ │ │ ├── status-cell.tsx
│ │ │ └── time-cell.tsx
│ │ ├── index.ts
│ │ ├── network-table.tsx
│ │ ├── table-body.tsx
│ │ ├── table-header.tsx
│ │ └── table-row.tsx
│ ├── network-header/ # 네트워크 헤더
│ │ ├── index.ts
│ │ ├── model/
│ │ │ ├── consts.ts
│ │ │ └── index.ts
│ │ └── ui/
│ │ ├── index.ts
│ │ ├── network-controls.tsx
│ │ ├── network-filters.tsx
│ │ ├── network-header.tsx
│ │ └── network-stats.tsx
│ └── host-path-tree/ # 호스트 경로 트리
│ ├── hooks/
│ │ ├── index.ts
│ │ ├── use-host-tree.ts
│ │ └── use-node-actions.ts
│ ├── index.ts
│ ├── lib/
│ │ ├── index.ts
│ │ ├── node-ui-utils.tsx
│ │ ├── tree-builder.ts
│ │ └── utils.ts
│ ├── model/
│ │ ├── index.ts
│ │ └── types.ts
│ └── ui/
│ ├── host-path-tree.tsx
│ ├── index.ts
│ ├── node-content.tsx
│ ├── transaction-list.tsx
│ └── tree-node.tsx
├── features/ # 기능 레이어
│ ├── network-table/ # 네트워크 테이블 기능
│ │ └── api/
│ ├── transaction-details/ # 트랜잭션 상세
│ │ ├── context/
│ │ │ └── form-context.tsx
│ │ ├── hooks/
│ │ │ ├── index.ts
│ │ │ ├── use-transaction-edit.ts
│ │ │ └── use-transaction-tabs.ts
│ │ ├── index.ts
│ │ ├── lib/
│ │ │ ├── index.ts
│ │ │ └── utils.ts
│ │ ├── model/
│ │ │ ├── consts.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── ui/
│ │ ├── form-components.tsx
│ │ ├── index.ts
│ │ ├── transaction-body.tsx
│ │ ├── transaction-details.tsx
│ │ ├── transaction-header.tsx
│ │ ├── transaction-headers.tsx
│ │ └── transaction-response.tsx
│ └── websocket-test/ # WebSocket 테스트
│ └── ui/
├── entities/ # 엔티티 레이어
│ ├── proxy/ # 프록시 엔티티
│ │ ├── index.ts
│ │ └── model/
│ │ ├── data-type.ts
│ │ ├── index.ts
│ │ └── types.ts
│ ├── session/ # 세션 엔티티
│ │ ├── index.ts
│ │ └── model/
│ │ ├── index.ts
│ │ └── types.ts
│ └── transaction/ # 트랜잭션 엔티티
│ ├── index.ts
│ └── lib/
│ ├── index.ts
│ └── utils.ts
└── shared/ # 공유 레이어
├── api/ # API 클라이언트
│ └── proxy.ts
├── app-sidebar/ # 앱 사이드바
│ ├── hooks/
│ │ ├── index.ts
│ │ └── use-sidebar-collapse.ts
│ ├── index.ts
│ ├── model/
│ │ ├── consts.ts
│ │ ├── index.ts
│ │ ├── sidebar-store.ts
│ │ └── types.ts
│ └── ui/
│ ├── app-sidebar.tsx
│ ├── index.ts
│ ├── sidebar-header.tsx
│ ├── sidebar-navigation.tsx
│ └── sidebar-status.tsx
├── assets/ # 정적 에셋
│ ├── index.ts
│ └── logo.png
├── lib/ # 유틸리티 함수
│ ├── class-name.ts
│ └── index.ts
├── stores/ # 상태 관리
│ ├── index.ts
│ ├── proxy-store.ts
│ └── session-store.ts
└── ui/ # UI 컴포넌트
├── badge.tsx
├── button.tsx
├── card.tsx
├── command.tsx
├── dialog.tsx
├── index.ts
├── input.tsx
├── layout.tsx
├── multi-select.tsx
├── popover.tsx
├── resizable.tsx
├── scroll-area.tsx
├── select.tsx
├── separator.tsx
├── sidebar.tsx
├── sonner.tsx
├── tabs.tsx
├── textarea.tsx
└── virtualized-scroll-area.tsx#각 레이어의 역할
#1. app/ (애플리케이션 레이어)
- App.tsx: 루트 컴포넌트, 라우팅 설정
- layouts/: 공통 레이아웃 컴포넌트
- providers/: React Context 프로바이더
#2. pages/ (페이지 레이어)
- network-dashboard/: 메인 네트워크 모니터링 페이지
- sessions/: 세션 관리 페이지
#3. widgets/ (위젯 레이어)
- network-table/: 네트워크 요청 테이블
- network-header/: 네트워크 헤더 정보
- host-path-tree/: 호스트별 경로 트리
#4. features/ (기능 레이어)
- network-table/: 테이블 관련 기능 (필터링, 정렬 등)
- transaction-details/: 트랜잭션 상세 보기
- har-export/: HAR 1.2 형식으로 트랜잭션 내보내기
- websocket-test/: WebSocket 테스트 기능
#5. entities/ (엔티티 레이어)
- proxy/: 프록시 관련 데이터 모델
- session/: 세션 관련 데이터 모델
- transaction/: 트랜잭션 관련 데이터 모델
#6. shared/ (공유 레이어)
- api/: 백엔드 API 클라이언트
- ui/: 재사용 가능한 UI 컴포넌트
- lib/: 유틸리티 함수
- stores/: Zustand 상태 관리
- assets/: 정적 에셋
#Tauri 백엔드 (desktop/src-tauri/)
src-tauri/
├── Cargo.toml # Tauri 백엔드 설정
├── tauri.conf.json # Tauri 설정
├── src/
│ ├── main.rs # 메인 진입점
│ ├── lib.rs # 라이브러리 진입점
│ ├── proxy.rs # 레거시 프록시
│ ├── proxy_v2.rs # 새로운 프록시
│ └── certificate_authority/ # CA 관리
│ ├── cheolsu-proxy.cnf # OpenSSL 설정 파일
│ └── cheolsu-proxy.srl # OpenSSL 직렬 번호 파일
├── capabilities/ # Tauri 권한 설정
├── icons/ # 앱 아이콘
└── gen/ # 자동 생성 파일#Tauri 설정
// tauri.conf.json
{
"build": {
"beforeDevCommand": "bun run dev",
"beforeBuildCommand": "bun run build",
"devPath": "http://localhost:1420",
"distDir": "../dist"
},
"package": {
"productName": "Cheolsu Proxy",
"version": "0.1.0"
}
}#데이터 플로우
#1. 프록시 요청 처리
sequenceDiagram
participant Client as 클라이언트
participant Proxy as 프록시 서버
participant CA as CA 관리자
participant Target as 대상 서버
Client->>Proxy: HTTP/HTTPS 요청
Proxy->>Proxy: 요청 분석
alt HTTPS 요청
Proxy->>CA: 인증서 요청
CA-->>Proxy: 동적 인증서
Proxy->>Client: TLS 핸드셰이크
end
Proxy->>Target: 요청 전달
Target-->>Proxy: 응답
Proxy-->>Client: 응답 전달#2. 프론트엔드 데이터 플로우
graph TD
A[Tauri Backend] --> B[Tauri Invoke API]
B --> C[React Components]#상태 관리
#Zustand 스토어 구조
// stores/proxy-store.ts
interface ProxyStore {
// 상태
isRunning: boolean;
listenAddr: string;
requests: Transaction[];
// 액션
startProxy: () => void;
stopProxy: () => void;
addRequest: (request: Transaction) => void;
clearRequests: () => void;
}
// stores/session-store.ts
interface SessionStore {
// 상태
sessions: Session[];
activeSession: string | null;
// 액션
createSession: () => void;
switchSession: (id: string) => void;
deleteSession: (id: string) => void;
}#API 통신
#Tauri Invoke API
// shared/api/proxy.ts
import { invoke } from "@tauri-apps/api/core";
export async function fetchProxyStatus(): Promise<boolean> {
return await invoke("proxy_status");
}
export async function startProxy(address: string): Promise<void> {
return await invoke("start_proxy", { addr: address });
}
export async function stopProxy(): Promise<void> {
return await invoke("stop_proxy");
}
// proxyapi_v2를 사용하는 새로운 프록시 함수들
export interface ProxyStartResult {
status: boolean;
message: string;
}
export async function startProxyV2(port: number = 8100): Promise<ProxyStartResult> {
return invoke("start_proxy_v2", { addr: `127.0.0.1:${port}` });
}
export async function stopProxyV2(): Promise<void> {
return invoke("stop_proxy_v2");
}
export async function getProxyV2Status(): Promise<boolean> {
return invoke("proxy_v2_status");
}#테스트 구조
#Rust 테스트
tests/
├── common/ # 공통 테스트 유틸리티
│ └── mod.rs
├── integration_error_handling_tests.rs
├── logging_handler_error_tests.rs
├── openssl_ca.rs
├── rcgen_ca.rs
└── websocket.rs#프론트엔드 테스트
__tests__/
├── components/ # 컴포넌트 테스트
├── pages/ # 페이지 테스트
├── utils/ # 유틸리티 테스트
└── setup.ts # 테스트 설정#성능 최적화
#백엔드 최적화
- 비동기 처리: tokio 런타임 사용
- 메모리 풀링: 객체 풀 패턴 적용
- 스트리밍: 대용량 데이터 스트리밍 처리
#프론트엔드 최적화
- 가상화: 대용량 리스트 가상화
- 메모이제이션: React.memo, useMemo 사용
- 코드 스플리팅: 동적 import 사용
#보안 고려사항
#백엔드 보안
- 인증서 관리: 안전한 CA 인증서 생성
- 메모리 보안: 안전한 메모리 관리
- 입력 검증: 모든 입력 데이터 검증
#프론트엔드 보안
- XSS 방지: 입력 데이터 이스케이핑
- CSRF 방지: 토큰 기반 인증
- 콘텐츠 보안 정책: CSP 헤더 설정
#확장성
#플러그인 시스템 (향후)
// 플러그인 트레이트
pub trait Plugin {
fn name(&self) -> &str;
fn version(&self) -> &str;
fn handle_request(&self, request: &mut Request) -> Result<(), Error>;
fn handle_response(&self, response: &mut Response) -> Result<(), Error>;
}이 구조를 이해하면 Cheolsu Proxy의 코드베이스를 효과적으로 탐색하고 기여할 수 있습니다.
