@@ -104,6 +104,54 @@ type dirResp struct {
104
104
Items []dirItem `json:"items"`
105
105
}
106
106
107
+ func forRespItems (jsonStream io.ReadCloser , workFunc func (* dirItem ) error ) error {
108
+ dec := json .NewDecoder (jsonStream )
109
+
110
+ // find items list
111
+ for {
112
+ t , err := dec .Token ()
113
+ if err != nil {
114
+ return err
115
+ }
116
+
117
+ if t == "items" {
118
+ t , err := dec .Token ()
119
+ if err != nil {
120
+ return err
121
+ }
122
+ if t != json .Delim ('[' ) {
123
+ return fmt .Errorf ("JSON items is not list" )
124
+ }
125
+ break
126
+ }
127
+ dec .More ()
128
+ }
129
+
130
+ // read items
131
+ for dec .More () {
132
+ var i dirItem
133
+ err := dec .Decode (& i )
134
+ if err != nil {
135
+ break
136
+ }
137
+ err = workFunc (& i )
138
+ if err != nil {
139
+ return err
140
+ }
141
+ }
142
+
143
+ // check items list closed
144
+ t , err := dec .Token ()
145
+ if err != nil {
146
+ return err
147
+ }
148
+ if t != json .Delim (']' ) {
149
+ return fmt .Errorf ("items loading is not completed" )
150
+ }
151
+
152
+ return nil
153
+ }
154
+
107
155
func recursiveDownload (ctx context.Context , sClient * safeClient.SafeClient , log * slog.Logger , sem chan struct {}, url , srcPath , dstPath string ) (err error ) {
108
156
select {
109
157
case <- ctx .Done ():
@@ -135,22 +183,11 @@ func recursiveDownload(ctx context.Context, sClient *safeClient.SafeClient, log
135
183
}
136
184
137
185
if srcPath != "" && srcPath [len (srcPath )- 1 :] == "/" {
138
- dirListBody , err := io .ReadAll (resp .Body )
139
- if err != nil {
140
- return fmt .Errorf ("Response body (%s) error: %s" , srcPath , err .Error ())
141
- }
142
-
143
- var dir dirResp
144
- err = json .Unmarshal (dirListBody , & dir )
145
- if err != nil {
146
- return fmt .Errorf ("Invalid dir (%s) data: %s" , srcPath , err .Error ())
147
- }
148
-
149
186
var wg sync.WaitGroup
150
187
var mu sync.Mutex
151
188
var firstErr error
152
189
153
- for _ , item := range dir . Items {
190
+ err = forRespItems ( resp . Body , func ( item * dirItem ) error {
154
191
subPath := item .Name
155
192
if item .Type == "dir" {
156
193
err = os .MkdirAll (filepath .Join (dstPath , subPath ), os .ModePerm )
@@ -172,7 +209,13 @@ func recursiveDownload(ctx context.Context, sClient *safeClient.SafeClient, log
172
209
mu .Unlock ()
173
210
}
174
211
}(subPath )
212
+
213
+ return nil
214
+ })
215
+ if err != nil {
216
+ return fmt .Errorf ("Response body (%s) error: %s" , srcPath , err .Error ())
175
217
}
218
+
176
219
wg .Wait ()
177
220
return firstErr
178
221
} else {
0 commit comments