mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-09-29 14:06:36 +08:00
4e8ec23264
完成 V2 Phase 0 安全与一致性前置:统一真实归档限额、流式拉取、候选裁剪、保留上传删除语义及 Pages 路由引用锁。
110 lines
3.8 KiB
Go
110 lines
3.8 KiB
Go
// Copyright 2026 Arctel.net
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package httpclient
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestDownloadPagesProjectLatestPackageRejectsChunkedBodyOverLimit(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
if flusher, ok := w.(http.Flusher); ok {
|
|
flusher.Flush()
|
|
}
|
|
_, _ = io.WriteString(w, "123456")
|
|
}))
|
|
defer server.Close()
|
|
|
|
client := New(server.URL, "test-token", time.Second)
|
|
var dst bytes.Buffer
|
|
written, err := client.DownloadPagesProjectLatestPackage(
|
|
context.Background(),
|
|
7,
|
|
&dst,
|
|
4,
|
|
)
|
|
if err == nil || !strings.Contains(err.Error(), "body exceeds limit") {
|
|
t.Fatalf("DownloadPagesProjectLatestPackage(chunked, limit=4) error = %v, want body limit error", err)
|
|
}
|
|
if written != 5 {
|
|
t.Errorf("DownloadPagesProjectLatestPackage(chunked, limit=4) written = %d, want 5", written)
|
|
}
|
|
}
|
|
|
|
func TestCopyPagesPackageResponseRejectsAdvertisedContentLengthBeforeWrite(t *testing.T) {
|
|
response := &http.Response{
|
|
Body: io.NopCloser(strings.NewReader("123456")),
|
|
ContentLength: 6,
|
|
}
|
|
var dst bytes.Buffer
|
|
written, err := copyPagesPackageResponse(&dst, response, 4)
|
|
if err == nil || !strings.Contains(err.Error(), "Content-Length") {
|
|
t.Fatalf("copyPagesPackageResponse(Content-Length=6, limit=4) error = %v, want Content-Length limit error", err)
|
|
}
|
|
if written != 0 || dst.Len() != 0 {
|
|
t.Errorf("copyPagesPackageResponse(Content-Length=6, limit=4) wrote (%d, %d buffered), want no writes", written, dst.Len())
|
|
}
|
|
}
|
|
|
|
func TestCopyPagesPackageResponseRejectsForgedSmallContentLength(t *testing.T) {
|
|
response := &http.Response{
|
|
Body: io.NopCloser(strings.NewReader("123456")),
|
|
ContentLength: 2,
|
|
}
|
|
var dst bytes.Buffer
|
|
written, err := copyPagesPackageResponse(&dst, response, 4)
|
|
if err == nil || !strings.Contains(err.Error(), "body exceeds limit") {
|
|
t.Fatalf("copyPagesPackageResponse(forged Content-Length=2, limit=4) error = %v, want body limit error", err)
|
|
}
|
|
if written != 5 {
|
|
t.Errorf("copyPagesPackageResponse(forged Content-Length=2, limit=4) written = %d, want 5", written)
|
|
}
|
|
}
|
|
|
|
func TestDownloadPagesProjectLatestPackageBoundsChunkedErrorResponse(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
if flusher, ok := w.(http.Flusher); ok {
|
|
flusher.Flush()
|
|
}
|
|
_, _ = io.WriteString(w, strings.Repeat("x", int(pagesControlResponseMaxBytes+1)))
|
|
}))
|
|
defer server.Close()
|
|
|
|
client := New(server.URL, "test-token", time.Second)
|
|
var dst bytes.Buffer
|
|
_, err := client.DownloadPagesProjectLatestPackage(context.Background(), 7, &dst, 1024)
|
|
if err == nil || !strings.Contains(err.Error(), "control response body exceeds limit") {
|
|
t.Fatalf("DownloadPagesProjectLatestPackage(large chunked 400) error = %v, want bounded response error", err)
|
|
}
|
|
if dst.Len() != 0 {
|
|
t.Errorf("DownloadPagesProjectLatestPackage(large chunked 400) wrote %d package bytes, want 0", dst.Len())
|
|
}
|
|
}
|
|
|
|
func TestGetPagesProjectLatestHashBoundsChunkedMetadataResponse(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
if flusher, ok := w.(http.Flusher); ok {
|
|
flusher.Flush()
|
|
}
|
|
_, _ = io.WriteString(w, strings.Repeat("x", int(pagesControlResponseMaxBytes+1)))
|
|
}))
|
|
defer server.Close()
|
|
|
|
client := New(server.URL, "test-token", time.Second)
|
|
_, err := client.GetPagesProjectLatestHash(context.Background(), 7)
|
|
if err == nil || !strings.Contains(err.Error(), "control response body exceeds limit") {
|
|
t.Fatalf("GetPagesProjectLatestHash(large chunked metadata) error = %v, want bounded response error", err)
|
|
}
|
|
}
|