
교안: 공봉식, <Tucker의 Go 언어 프로그래밍>, 2021
Tucker Programming 유튜브 Link
교안 Github Link
[Preview]
HTTP (Hypertext Transfer Protocol) 는 인터넷에서 데이터를 주고받는 통신 프로토콜
클라이언트/서버 구조에서 클라이언트는 서버에 "요청"을 하고, 서버는 클라이언트로 "응답"을 한다
HTTP는 "비연결성" 특징이 있다
HTTPS (Hypertext Transfer Protocol)는 HTTP의 암호화 통신 버전
HTTP 프로토콜의 기본 통신 포트는 80포트, HTTPS 프로토콜의 기본 통신 포트는 443포트
HTTP 프로토콜을 사용하여 요청에 대한 응답을 하는 서버를 웹 서버 혹은 HTTP 서버
GO는 웹 서버를 쉽게 만들 수 있도록 기본 패키지로 net/http 패키지 제공
HTTP는 비연결성 통신이라 자원 낭비를 줄일 수 있지만, 클라이언트의 상태를 유지할 수 없다는 단점 있다
HTTP를 사용하면 다양한 요청에 대한 처리를 할 수 있다
HTTPS를 사용하면 통신 내용을 암호화하므로 더 안전하다
GO 언어를 이용해 만든 웹 서버는 뛰어난 성능을 자랑한다
GO 언어에서는 net/http 패키지를 사용하여 웹 서버를 만들 수 있다
GO 언어에서 웹 서버를 만들려면 < 핸들러 등록 >과 < 웹 서버 시작 >이라는 두 단계를 거쳐야 한다
각 HTTP 요청 URL 경로에 대응할 수 있는 핸들러를 등록한다
핸들러는 HandleFunc() 함수로 등록
http.HandleFunc는 URL 패턴과 이 패턴에 대응하는 함수를 등록하는 방법http.HandlerFunc 타입의 함수func(http.ResponseWriter, *http.Request) 시그니처를 가진 함수를 http.Handler 인터페이스로 래핑
Handle() 함수로는 http.Handler() 인터페이스를 구현한 객체 등록http.Handle 함수는 http.Handler 인터페이스를 직접 구현하는 객체를 사용하여 특정 URL 패턴에 대한 요청을 처리http.Handler 인터페이스는 단 하나의 메서드인 ServeHTTP(http.ResponseWriter, *http.Request)를 가짐
-> 그러면 URL 경로에 해당하는 HTTP 요청 수신 시
http.Handler 객체의 인터페이스인 ServeHTTP() 메서드를 호출하여 요청에 따른 로직 수행할 수 있다
func IndexPathHandler(w http.ResponseWriter, r *http.Request){
...
}
http.HandelFunc("/", IndexPathHandler)
IndexPathHandler() 함수 정의IndexPathHandler() 함수를 http.HandlerFunc 타입으로 변환하여 http.Handler 인터페이스를 만족하게 한다http.HandleFunc() 함수로 "/" 경로 에 대해서 IndexPathHandler 함수 등록"/" 경로에 해당하는 HTTP 요청을 수신할 때, IndexPathHandler() 함수 호출한다![추가]
http 패키지의 Request 구조체에는 HTTP 요청 정보가 담겨있다.
각 경로에 대한 핸들러 등록을 마치면, 본격적으로 웹 서버를 시작하게 된다
ListenAndServe() 함수 호출해 웹 서버 시작 : ListenAndServe(addr string, handler Handler) error
addr : HTTP 요청을 수신하는 주소, 일반적으로 ":3000"과 같이 요청 수신하는 포트 번호 작성handler : 핸들러 인스턴스, nil로 값 넣으면 디폴트 핸들러(DefaultServeMux) 실행된다, 패키지 함수인 http.HandleFunc()로 핸들러 함수 등록할 때는 두 번째 인수로 nil 넣어준다. DefaultServeMux 는 http.HandleFunc() 함수 호출해 등록된 핸들러 사용localhost란 현재 컴퓨터를 나타내는 키워드
http://localhost:3000 은 현재 컴퓨터의 3000번 포트에 HTTP 요청을 보내라는 뜻"/"는 루트 경로
http.Request에는 클라이언트에서 보낸 메서드(method), 헤더(header), 바디(body) 같은 HTTP 요청 정보를 가진다.
fmt 패키지의 Fprint()는 출력 스트림에 값을 쓰는 함수
http.ResponseWriter 타입을 출력 스트림으로 지정http.ResponseWriter 타입에 값을 쓰면 HTTP 응답으로 전송된다웹 서버는 위와 같이 핸들러를 먼저 등록하고, ListenAndServe를 통해서 웹 서버를 시작한다.
그리고 사용자에 요청을 보내면 등록된 핸들러가 있는지 확인하고 핸들러를 실행한다.
우리가 웹 브라우저에 https://goldenrabbit.co.kr:3000을 입력한 뒤 enter 키를 눌렀을 때 일어나는 일을 생각해보자.
goldenrabbit.co.kr, 포트 번호 : 30001) 웹 브라우저는 먼저 도메인 네임 시스템 Domain Name System에 도메인에 해당하는 IP 주소 요청
2) 포트 번호 없이 http://goldenrabbit.co.kr 입력하면?
3) https://
4) HTTP
5) 웹 서버
: 특정 포트에서 대기하며 사용자의 HTTP 요청에 HTTP 응답을 전송하는 서버, 이때 응답은 일반적으로 HTML 문서 전송
HTTP 요청에 포함된 쿼리 인수를 읽고 사용하는 방법을 알아보자
HTTP 요청을 만들 때 필요한 인수를 쿼리 인수로 담을 수 있다
http://localhost?id=1&name=abcd 와 같이 쿼리 인수 입력 : id와 name을 인수로, 값은 각각 1과 abcd?를 붙여서 쿼리 인수가 시작됨을 표시 key=value 형태로 입력&를 사용해서 인수 연결앞서 ListenAndServe() 함수 두 번째 인수로 nil 넣어서 DefaultServeMux 사용한다 학습
DefaultServeMux 사용하면 http.HandleFunc() 함수 같은 패키지 함수들을 이용해서 등록한 핸들러를 사용하기 때문에, 다양한 기능을 추가하기 어려운 문제가 있다
http.NewServeMux() 함수 이용해 새로운 ServeMux 인스턴스 생성
http.HandleFunc() 함수는 DefaultServeMux에 핸들러를 등록하는 반면,mux.HandleFunc() 메서드는 ServeMux 인스턴스에 핸들러 등록ServeMux 인스턴스를 사용하면 핸들러에 다양한 기능을 추가하기가 쉬워진다.
[추가]
MUX : multiplexer의 약자로, 여러 입력 중 하나를 선택해서 반환하는 디지털 장치
HTML은 하이퍼텍스트 문서 포맷으로 문자뿐 아니라, 이미지나 음악 등 멀티미디어 컨텐츠를 포함할 수 있다
HTML 문서가 이미지나 음악 데이터를 직접 포함하는 형태가 아니라, 이미지나 음악 파일의 경로 URL을 포함하는 형태로 데이터를 담는다
<img> 태그의 src 값으로 이미지 경로만 가진다func main(){
http.HandleFunc("/", http.FileServer(http.Dir("static")))
http.ListenAndServe(":3000", nil)
}
"/" 경로에 대한 요청이 올때, static 폴더 아래 있는 파일들을 제공한다HTTP는 하이퍼텍스트, 즉 HTML 문서를 전송하는 프로토콜이지만 HTML 문서뿐 아니라 이미지나 다양한 데이터도 전송 가능
JSON은 자바스크립트 오브젝트 표기법의 약자로, 말 그대로 자바스크립트에서 오브젝트를 표현하는 방법으로 사용되는 포맷
{ 로 표기, } 로 종료 "key":value 형태로 표기, 로 구분[ ] 로 표기" "로 묶어서 표기func StudentHandler(w http.ResponseWriter, r *http.Request){
var student = Student{"aaa", 16, 87}
data, _ := json.Marshal(student) // Student 객체를 JSON 포맷으로 변환
w.Header().Add("content-type", "application/json") // JSON 포맷임을 표시
w.WriteHeader(http.StatusOk)
fmt.Fprint(w, string(data) // ResponseWriter로 JSON 데이터를 문자열 타입으로 변환해 사용
}
http.ResponseWriter 객체이고, r은 요청 정보를 담고 있는 *http.Request 객체json.Marshal 함수는 주어진 객체(student)를 JSON 포맷의 바이트 슬라이스로 변환[ ]byte 타입으로 반환된다json.NewDecoder(res.Body).Decode(student)를 통해 JSON 데이터를 Student 객체로 변환HTTPS를 지원하는 웹 서버를 만들어보자
HTTPS는 HTTP에 보안 기능을 강화한 프로토콜
웹 서버를 시작할 때 ListenAndServe() 함수가 아니라, ListenAndServeTLS() 함수를 사용
HTTPS는 기존 HTTP 요청과 응답을 공개키 암호화 방식을 사용해서 암호화한 프로토콜
HTTPS 서버를 실행하려면 인증서와 비밀키를 생성해야 한다.
본래 인증서는 인증기관에서 발급해야 한다. 혹은 셀프 인증
openssl 프로그램 설치x509 사용해서 인증서 발급localhost.crt 파일에 포함되어 있다localhost.crt 파일로 인증 정보와 공개키 전송하게 된다