Compare commits

...
Author SHA1 Message Date
修雨 015daae064 fix: disable Expect for Gitee uploads 2026-07-22 15:02:13 +08:00
修雨 e7510ea5f0 Merge pull request #758 from DingTalk-Real-AI/codex/fix-gitee-upload-timeouts
fix: harden Gitee release repair
2026-07-22 14:39:15 +08:00
2 changed files with 41 additions and 9 deletions
+3 -1
View File
@@ -243,7 +243,9 @@ gitee_attach() {
if response="$(curl -fsS --connect-timeout "$GITEE_CURL_CONNECT_TIMEOUT" \
--max-time "$max_time" \
-X POST "${base}/releases/${release_id}/attach_files" \
-H "Authorization: token ${GITEE_TOKEN}" -F "file=@${file}" 2>&1)"; then
-H "Authorization: token ${GITEE_TOKEN}" \
-H "Expect:" \
-F "file=@${file}" 2>&1)"; then
status=0
else
status=$?
+38 -8
View File
@@ -416,6 +416,31 @@ func TestReconcileGiteeAssetsRecoversACommittedUploadWithLostResponse(t *testing
}
}
func TestReconcileGiteeAssetsDisablesExpectContinueForLargeUploads(t *testing.T) {
scriptPath := mustAbs(t, filepath.Join("..", "..", "scripts", "release", "reconcile-gitee-assets.sh"))
distDir := seedGiteeDist(t)
mustWriteFile(
t,
filepath.Join(distDir, requiredGiteeAssets[0]),
[]byte(strings.Repeat("x", 2<<20)),
0o644,
)
fake := newFakeGiteeRelease(false, false)
fake.rejectExpectContinue = true
server := httptest.NewServer(fake)
defer server.Close()
cmd := exec.Command("bash", scriptPath)
cmd.Env = giteeAssetEnv(distDir, server.URL, "1")
output, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("large-asset reconciliation error = %v\noutput:\n%s", err, output)
}
if !strings.Contains(string(output), "all 8 verified") {
t.Fatalf("large-asset reconciliation did not verify every asset:\n%s", output)
}
}
func TestReconcileGiteeAssetsFailsWhenAnyUploadIsMissing(t *testing.T) {
scriptPath := mustAbs(t, filepath.Join("..", "..", "scripts", "release", "reconcile-gitee-assets.sh"))
distDir := seedGiteeDist(t)
@@ -754,14 +779,15 @@ type fakeGiteeAsset struct {
}
type fakeGiteeRelease struct {
mu sync.Mutex
nextID int
assets map[int]fakeGiteeAsset
uploadCalls map[string]int
dropFirstResponse bool
droppedResponse bool
failUploads bool
uploadDelay time.Duration
mu sync.Mutex
nextID int
assets map[int]fakeGiteeAsset
uploadCalls map[string]int
dropFirstResponse bool
droppedResponse bool
failUploads bool
uploadDelay time.Duration
rejectExpectContinue bool
}
func newFakeGiteeRelease(dropFirstResponse, failUploads bool) *fakeGiteeRelease {
@@ -820,6 +846,10 @@ func (f *fakeGiteeRelease) list(w http.ResponseWriter, r *http.Request) {
}
func (f *fakeGiteeRelease) upload(w http.ResponseWriter, r *http.Request) {
if f.rejectExpectContinue && r.Header.Get("Expect") != "" {
http.Error(w, "Expect: 100-continue is not supported", http.StatusExpectationFailed)
return
}
if err := r.ParseMultipartForm(32 << 20); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return