Skip to content

Instantly share code, notes, and snippets.

@yeonwooz
Last active November 9, 2022 06:27
Show Gist options
  • Save yeonwooz/80c56875973321ce2fb7f214938d7903 to your computer and use it in GitHub Desktop.
Save yeonwooz/80c56875973321ce2fb7f214938d7903 to your computer and use it in GitHub Desktop.
proxy_main
// https://github.com/yeonwooz/webproxy-lab
int main(int argc, char **argv) {
int listenfd, clientfd;
socklen_t clientlen;
struct sockaddr_storage clientaddr;
char client_hostname[MAXLINE], client_port[MAXLINE]; // 프록시가 요청을 받고 응답해줄 클라이언트의 IP, Port
if (argc != 2) {
fprintf(stderr, "usage: %s <port>\n", argv[0]);
exit(0);
}
listenfd = Open_listenfd(argv[1]); // 대기 회선
while (1) {
clientlen = sizeof(struct sockaddr_storage);
clientfd = Accept(listenfd, (SA *)&clientaddr, &clientlen); // 프록시가 서버로서 클라이언트와 맺는 파일 디스크립터(소켓 디스크립터) : 고유 식별되는 회선이자 메모리 그 자체
Getnameinfo((SA *)&clientaddr, clientlen, client_hostname, MAXLINE, client_port, MAXLINE, 0);
doit(clientfd); // 프록시가 중개를 시작
Close(clientfd);
}
return 0;
}
void doit(int client_fd) {
// 1.클라이언트와의 fd를 클라이언트용 rio에 연결(Rio_readinitb)한다. rio는 Registered Input/Output 라는 소켓 API 이다. 메시지를 보낼 수 있는 텍스트창으로 보면 됨.
// 2.클라이언트의 요청을 한줄 읽어들여서(Rio_readlineb) 메서드와 URI, HTTP 버전을 얻고, URI에서 목적지 호스트와 포트를 뽑아낸다.
// 3.목적지 호스트와 포트를 가지고 서버용 fd를 생성하고, 서버용 rio에 연결(Rio_readinitb)한다.
// 4.클라이언트가 보낸 첫줄을 이미 읽어 유실되었고, HTTP 버전을 바꾸거나 추가 헤더를 붙일 필요가 있으므로,
// 클라이언트가 보내는 메시지를 한줄씩 읽어들이면서(Rio_readlineb) 재조합하여 서버에 보낼 HTTP 요청메시지를 새로 생성해준다.
// 5.서버에 요청메시지를 보낸다.(Rio_writen)
// 6.서버 응답이 오면 클라이언트에게 전달한다. (Rio_readnb, Rio_writen)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment