72 lines
2 KiB
Go
72 lines
2 KiB
Go
package claude
|
|
|
|
import (
|
|
"bytes"
|
|
"compress/flate"
|
|
"compress/gzip"
|
|
"compress/lzw"
|
|
"compress/zlib"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/andybalholm/brotli"
|
|
)
|
|
|
|
func readClaudeOAuthResponseBody(resp *http.Response) ([]byte, error) {
|
|
if resp == nil || resp.Body == nil {
|
|
return nil, fmt.Errorf("read Claude OAuth response: body is nil")
|
|
}
|
|
encoded, errRead := io.ReadAll(resp.Body)
|
|
if errRead != nil {
|
|
return nil, errRead
|
|
}
|
|
encodings := strings.Split(strings.Join(resp.Header.Values("Content-Encoding"), ","), ",")
|
|
for index := len(encodings) - 1; index >= 0; index-- {
|
|
encoding := strings.ToLower(strings.TrimSpace(encodings[index]))
|
|
if encoding == "" || encoding == "identity" {
|
|
continue
|
|
}
|
|
var errDecode error
|
|
encoded, errDecode = decodeClaudeOAuthEncoding(encoded, encoding)
|
|
if errDecode != nil {
|
|
return nil, errDecode
|
|
}
|
|
}
|
|
return encoded, nil
|
|
}
|
|
|
|
func decodeClaudeOAuthEncoding(encoded []byte, encoding string) ([]byte, error) {
|
|
var reader io.ReadCloser
|
|
switch encoding {
|
|
case "gzip":
|
|
gzipReader, errGzip := gzip.NewReader(bytes.NewReader(encoded))
|
|
if errGzip != nil {
|
|
return nil, fmt.Errorf("decode Claude OAuth gzip response: %w", errGzip)
|
|
}
|
|
reader = gzipReader
|
|
case "deflate":
|
|
zlibReader, errZlib := zlib.NewReader(bytes.NewReader(encoded))
|
|
if errZlib == nil {
|
|
reader = zlibReader
|
|
} else {
|
|
reader = flate.NewReader(bytes.NewReader(encoded))
|
|
}
|
|
case "br":
|
|
reader = io.NopCloser(brotli.NewReader(bytes.NewReader(encoded)))
|
|
case "compress":
|
|
reader = lzw.NewReader(bytes.NewReader(encoded), lzw.MSB, 8)
|
|
default:
|
|
return nil, fmt.Errorf("decode Claude OAuth response: unsupported content encoding %q", encoding)
|
|
}
|
|
decoded, errDecoded := io.ReadAll(reader)
|
|
if errDecoded != nil {
|
|
_ = reader.Close()
|
|
return nil, fmt.Errorf("decode Claude OAuth %s response: %w", encoding, errDecoded)
|
|
}
|
|
if errClose := reader.Close(); errClose != nil {
|
|
return nil, fmt.Errorf("close Claude OAuth %s decoder: %w", encoding, errClose)
|
|
}
|
|
return decoded, nil
|
|
}
|