feat(12-01): record multipart uploads and match Winter upload URLs
- attach.PublicURL and (*File).URL build Winter File::getPath() URLs; the thumbnailer decodes webp via golang.org/x/image v0.46.0 and checks the image size from the header before decoding - tide requests carry multipart parts (files beside the fixture pinned by sha256) encoded with the fixed MultipartBoundary, so PHP and Go receive byte-identical bodies - tide masks the random partition, disk name and file id of url/thumb_url upload URLs while still diffing prefix, size, mode and extension, and NormalizePublications masks Carbon dates in the published album
This commit is contained in:
@@ -25,13 +25,21 @@ func (b *Body) UnmarshalYAML(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadFlow reads and validates a version-1 YAML flow from path.
|
||||
// LoadFlow reads and validates a version-1 YAML flow from path. Request
|
||||
// part files are checked against their sha256, relative to path's directory.
|
||||
func LoadFlow(path string) (Flow, error) {
|
||||
raw, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return Flow{}, fmt.Errorf("tide: read %s: %w", path, err)
|
||||
}
|
||||
return ParseFlow(raw)
|
||||
flow, err := ParseFlow(raw)
|
||||
if err != nil {
|
||||
return Flow{}, err
|
||||
}
|
||||
if err := verifyPartFiles(filepath.Dir(path), flow); err != nil {
|
||||
return Flow{}, err
|
||||
}
|
||||
return flow, nil
|
||||
}
|
||||
|
||||
// ParseFlow decodes a version-1 YAML flow, rejecting unknown fields.
|
||||
@@ -163,6 +171,30 @@ func writeRequest(b *strings.Builder, indent int, req Request) {
|
||||
}
|
||||
writeHeaders(b, indent, req.Headers)
|
||||
writeBody(b, indent, string(req.Body))
|
||||
writeParts(b, indent, req.Parts)
|
||||
}
|
||||
|
||||
func writeParts(b *strings.Builder, indent int, parts []Part) {
|
||||
if len(parts) == 0 {
|
||||
return
|
||||
}
|
||||
pad := strings.Repeat(" ", indent)
|
||||
fmt.Fprintf(b, "%sparts:\n", pad)
|
||||
inner := strings.Repeat(" ", indent+2)
|
||||
for _, p := range parts {
|
||||
fmt.Fprintf(b, "%s- name: %s\n", inner, encodeScalar(p.Name))
|
||||
for _, kv := range [][2]string{
|
||||
{"value", p.Value},
|
||||
{"file", p.File},
|
||||
{"filename", p.Filename},
|
||||
{"content_type", p.ContentType},
|
||||
{"sha256", p.SHA256},
|
||||
} {
|
||||
if kv[1] != "" {
|
||||
fmt.Fprintf(b, "%s %s: %s\n", inner, kv[0], encodeScalar(kv[1]))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func writeResponse(b *strings.Builder, indent int, resp Response) {
|
||||
|
||||
Reference in New Issue
Block a user