@@ -15,6 +15,7 @@ using v8::Maybe;
1515using  v8::MaybeLocal;
1616using  v8::Nothing;
1717using  v8::Object;
18+ using  v8::Uint8Array;
1819using  v8::Value;
1920
2021//  Get a protocol string property from the object.
@@ -183,6 +184,7 @@ NetworkAgent::NetworkAgent(NetworkInspector* inspector,
183184  event_notifier_map_[" responseReceived"  ] = &NetworkAgent::responseReceived;
184185  event_notifier_map_[" loadingFailed"  ] = &NetworkAgent::loadingFailed;
185186  event_notifier_map_[" loadingFinished"  ] = &NetworkAgent::loadingFinished;
187+   event_notifier_map_[" dataReceived"  ] = &NetworkAgent::dataReceived;
186188}
187189
188190void  NetworkAgent::emitNotification (v8::Local<v8::Context> context,
@@ -211,6 +213,30 @@ protocol::DispatchResponse NetworkAgent::disable() {
211213  return  protocol::DispatchResponse::Success ();
212214}
213215
216+ protocol::DispatchResponse NetworkAgent::streamResourceContent (
217+     const  protocol::String& in_requestId, protocol::Binary* out_bufferedData) {
218+   if  (!requests_.contains (in_requestId)) {
219+     //  Request not found, ignore it.
220+     return  protocol::DispatchResponse::InvalidParams (" Request not found"  );
221+   }
222+ 
223+   auto & it = requests_[in_requestId];
224+ 
225+   it.is_streaming  = true ;
226+ 
227+   //  Concat response bodies.
228+   *out_bufferedData = protocol::Binary::concat (it.response_data_blobs );
229+   //  Clear buffered data.
230+   it.response_data_blobs .clear ();
231+ 
232+   if  (it.is_finished ) {
233+     //  If the request is finished, remove the entry.
234+     requests_.erase (in_requestId);
235+   }
236+ 
237+   return  protocol::DispatchResponse::Success ();
238+ }
239+ 
214240void  NetworkAgent::requestWillBeSent (v8::Local<v8::Context> context,
215241                                     v8::Local<v8::Object> params) {
216242  protocol::String request_id;
@@ -247,6 +273,12 @@ void NetworkAgent::requestWillBeSent(v8::Local<v8::Context> context,
247273                               std::move (initiator),
248274                               timestamp,
249275                               wall_time);
276+ 
277+   if  (requests_.contains (request_id)) {
278+     //  Duplicate entry, ignore it.
279+     return ;
280+   }
281+   requests_.emplace (request_id, RequestEntry{timestamp, false , false , {}});
250282}
251283
252284void  NetworkAgent::responseReceived (v8::Local<v8::Context> context,
@@ -295,6 +327,8 @@ void NetworkAgent::loadingFailed(v8::Local<v8::Context> context,
295327  }
296328
297329  frontend_->loadingFailed (request_id, timestamp, type, error_text);
330+ 
331+   requests_.erase (request_id);
298332}
299333
300334void  NetworkAgent::loadingFinished (v8::Local<v8::Context> context,
@@ -309,6 +343,63 @@ void NetworkAgent::loadingFinished(v8::Local<v8::Context> context,
309343  }
310344
311345  frontend_->loadingFinished (request_id, timestamp);
346+ 
347+   auto  request_entry = requests_.find (request_id);
348+   if  (request_entry == requests_.end ()) {
349+     //  No entry found. Ignore it.
350+     return ;
351+   }
352+ 
353+   if  (request_entry->second .is_streaming ) {
354+     //  Streaming finished, remove the entry.
355+     requests_.erase (request_id);
356+   } else  {
357+     request_entry->second .is_finished  = true ;
358+   }
359+ }
360+ 
361+ void  NetworkAgent::dataReceived (v8::Local<v8::Context> context,
362+                                 v8::Local<v8::Object> params) {
363+   protocol::String request_id;
364+   if  (!ObjectGetProtocolString (context, params, " requestId"  ).To (&request_id)) {
365+     return ;
366+   }
367+ 
368+   auto  request_entry = requests_.find (request_id);
369+   if  (request_entry == requests_.end ()) {
370+     //  No entry found. Ignore it.
371+     return ;
372+   }
373+ 
374+   double  timestamp;
375+   if  (!ObjectGetDouble (context, params, " timestamp"  ).To (×tamp)) {
376+     return ;
377+   }
378+   int  data_length;
379+   if  (!ObjectGetInt (context, params, " dataLength"  ).To (&data_length)) {
380+     return ;
381+   }
382+   int  encoded_data_length;
383+   if  (!ObjectGetInt (context, params, " encodedDataLength"  )
384+            .To (&encoded_data_length)) {
385+     return ;
386+   }
387+   Local<Object> data_obj;
388+   if  (!ObjectGetObject (context, params, " data"  ).ToLocal (&data_obj)) {
389+     return ;
390+   }
391+   if  (!data_obj->IsUint8Array ()) {
392+     return ;
393+   }
394+   Local<Uint8Array> data = data_obj.As <Uint8Array>();
395+   auto  data_bin = protocol::Binary::fromUint8Array (data);
396+ 
397+   if  (request_entry->second .is_streaming ) {
398+     frontend_->dataReceived (
399+         request_id, timestamp, data_length, encoded_data_length, data_bin);
400+   } else  {
401+     requests_[request_id].response_data_blobs .push_back (data_bin);
402+   }
312403}
313404
314405}  //  namespace inspector
0 commit comments