[go] net/http 패키지를 사용한 요청 취소 및 중지

Go 언어로 웹 서버나 클라이언트를 개발할 때 네트워크 요청을 취소하거나 중지해야 하는 경우가 있습니다. 특히 네트워크 요청이 오랜 시간 동안 대기하게 되면 리소스를 낭비할 뿐만 아니라 애플리케이션의 성능에도 영향을 미칠 수 있습니다. Go 언어의 net/http 패키지를 사용하면 요청을 취소하거나 중지하는 기능을 손쉽게 구현할 수 있습니다.

요청 취소

만약 HTTP 요청을 취소해야 한다면, http.Request 객체의 Context를 사용하여 요청을 취소할 수 있습니다. 아래 예시에서는 1초 이상 걸리는 요청을 할 때, 1초가 지나면 요청을 취소합니다.

package main

import (
	"context"
	"fmt"
	"net/http"
	"time"
)

func main() {
	req, err := http.NewRequest("GET", "https://example.com", nil)
	if err != nil {
		panic(err)
	}

	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
	defer cancel()
	req = req.WithContext(ctx)

	client := http.DefaultClient
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Request error:", err)
		return
	}
	defer resp.Body.Close()

	fmt.Println("Response status:", resp.Status)
}

간단히 context.WithTimeout을 사용하여 요청에 대한 제한 시간을 설정하고, req.WithContext를 통해 요청에 새로운 context를 추가합니다. 이후, 해당 context의 타임아웃 또는 취소가 발생하면 요청이 취소됩니다.

요청 중지

이미 실행 중인 요청을 중지해야 한다면, http.Transport를 이용하여 요청을 중지할 수 있습니다. 아래 예시에서는 1초 이상 걸리는 요청을 할 때, 1초가 지나면 요청을 중지합니다.

package main

import (
	"fmt"
	"net/http"
	"time"
)

func main() {
	tr := &http.Transport{}
	client := &http.Client{Transport: tr}

	req, err := http.NewRequest("GET", "https://example.com", nil)
	if err != nil {
		panic(err)
	}

	go func() {
		time.Sleep(1 * time.Second)
		tr.CancelRequest(req)
	}()

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Request error:", err)
		return
	}
	defer resp.Body.Close()

	fmt.Println("Response status:", resp.Status)
}

http.TransportCancelRequest 메서드를 사용하여 실행 중인 요청을 중지할 수 있습니다.

이러한 방법을 사용하여, Go의 net/http 패키지를 활용하여 요청을 취소하고 중지하는 방법에 대해 알아보았습니다. 네트워크 요청을 안전하게 관리하여 애플리케이션의 성능을 최적화할 수 있습니다.

참고문헌: