mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-09-18 06:34:54 +08:00
fix(release): 修复发布一致性与并发边界
This commit is contained in:
+6
-2
@@ -33,7 +33,7 @@ func (s *Server) serveCDN(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, selectorErr.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
selected, selectErr := s.loadReleaseDistribution(r, channel, releaseID)
|
||||
selected, selectErr := s.loadReleaseDistribution(r, channel, releaseID, rel)
|
||||
if selectErr != nil {
|
||||
http.Error(w, selectErr.Error(), http.StatusServiceUnavailable)
|
||||
return
|
||||
@@ -72,7 +72,11 @@ func (s *Server) serveCDN(w http.ResponseWriter, r *http.Request) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
if (explicitRelease || s.cfg.RequireIndexed) && s.cfg.VerifySize {
|
||||
if explicitRelease && hasEntry && uint64(info.Size()) != entry.Bytes {
|
||||
http.Error(w, "size mismatch with release index", http.StatusConflict)
|
||||
return
|
||||
}
|
||||
if !explicitRelease && s.cfg.RequireIndexed && s.cfg.VerifySize {
|
||||
if hasEntry && entry.Bytes > 0 && uint64(info.Size()) != entry.Bytes {
|
||||
http.Error(w, "size mismatch with release index", http.StatusConflict)
|
||||
return
|
||||
|
||||
@@ -107,6 +107,11 @@ paths:
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
- name: destination
|
||||
in: query
|
||||
description: Optional release-relative path whose localized bytes and BLAKE3 are revalidated.
|
||||
schema:
|
||||
type: string
|
||||
- name: offset
|
||||
in: query
|
||||
schema:
|
||||
|
||||
@@ -139,12 +139,13 @@ func (e *releaseSelectorError) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
func (s *Server) loadReleaseDistribution(r *http.Request, channel, releaseID string) (*backendrpc.ReleaseDistributionPage, error) {
|
||||
func (s *Server) loadReleaseDistribution(r *http.Request, channel, releaseID, destination string) (*backendrpc.ReleaseDistributionPage, error) {
|
||||
return s.loadReleaseDistributionFrom(r, backendrpc.ReleaseDistributionParams{
|
||||
Channel: channel,
|
||||
ReleaseID: releaseID,
|
||||
Offset: 0,
|
||||
Limit: 1000,
|
||||
Channel: channel,
|
||||
ReleaseID: releaseID,
|
||||
Destination: destination,
|
||||
Offset: 0,
|
||||
Limit: 1000,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -154,6 +155,9 @@ func releaseDistributionParams(r *http.Request, channel, releaseID string) (back
|
||||
ReleaseID: releaseID,
|
||||
}
|
||||
query := r.URL.Query()
|
||||
if destination := strings.TrimSpace(query.Get("destination")); destination != "" {
|
||||
params.Destination = destination
|
||||
}
|
||||
if raw := strings.TrimSpace(query.Get("offset")); raw != "" {
|
||||
offset, err := strconv.ParseUint(raw, 10, 64)
|
||||
if err != nil || uint64(int(^uint(0)>>1)) < offset {
|
||||
@@ -196,10 +200,11 @@ func (s *Server) loadReleaseDistributionFrom(r *http.Request, params backendrpc.
|
||||
all := append([]backendrpc.ReleaseDistributionEntry(nil), result.Entries...)
|
||||
for offset := len(all); offset < result.Total; {
|
||||
next, nextErr := backend.ReleaseDistribution(r.Context(), backendrpc.ReleaseDistributionParams{
|
||||
Channel: params.Channel,
|
||||
ReleaseID: params.ReleaseID,
|
||||
Offset: offset,
|
||||
Limit: pageSize,
|
||||
Channel: params.Channel,
|
||||
ReleaseID: params.ReleaseID,
|
||||
Destination: params.Destination,
|
||||
Offset: offset,
|
||||
Limit: pageSize,
|
||||
})
|
||||
if nextErr != nil {
|
||||
return nil, nextErr
|
||||
|
||||
@@ -101,13 +101,14 @@ func TestReleaseHTTPForwardsTypedSelectionAndDoesNotFallback(t *testing.T) {
|
||||
}
|
||||
|
||||
recorder = httptest.NewRecorder()
|
||||
server.Handler().ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/v1/distribution?channel=localized&release_id=localized-1&offset=2&limit=10", nil))
|
||||
server.Handler().ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/v1/distribution?channel=localized&release_id=localized-1&destination=TableBundles%2FTableCatalog.bytes&offset=2&limit=10", nil))
|
||||
if recorder.Code != http.StatusOK {
|
||||
t.Fatalf("distribution status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
if len(backend.distributionParams) != 1 ||
|
||||
backend.distributionParams[0].Channel != "localized" ||
|
||||
backend.distributionParams[0].ReleaseID != "localized-1" ||
|
||||
backend.distributionParams[0].Destination != "TableBundles/TableCatalog.bytes" ||
|
||||
backend.distributionParams[0].Offset != 2 ||
|
||||
backend.distributionParams[0].Limit != 10 {
|
||||
t.Fatalf("distribution params=%#v", backend.distributionParams)
|
||||
|
||||
@@ -189,10 +189,11 @@ type ReleaseListParams struct {
|
||||
|
||||
// ReleaseDistributionParams selects a verified release for distribution.
|
||||
type ReleaseDistributionParams struct {
|
||||
Channel string `json:"channel,omitempty"`
|
||||
ReleaseID string `json:"release_id,omitempty"`
|
||||
Offset int `json:"offset,omitempty"`
|
||||
Limit int `json:"limit,omitempty"`
|
||||
Channel string `json:"channel,omitempty"`
|
||||
ReleaseID string `json:"release_id,omitempty"`
|
||||
Offset int `json:"offset,omitempty"`
|
||||
Limit int `json:"limit,omitempty"`
|
||||
Destination string `json:"destination,omitempty"`
|
||||
}
|
||||
|
||||
// ReleaseCleanupParams controls the dry-run/execute cleanup pair.
|
||||
|
||||
Reference in New Issue
Block a user