• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "quiche/http2/core/http2_trace_logging.h"
2 
3 #include <cstdint>
4 #include <memory>
5 
6 #include "absl/strings/str_cat.h"
7 #include "absl/strings/string_view.h"
8 #include "quiche/common/platform/api/quiche_bug_tracker.h"
9 #include "quiche/common/platform/api/quiche_logging.h"
10 #include "quiche/spdy/core/http2_header_block.h"
11 #include "quiche/spdy/core/spdy_protocol.h"
12 
13 // Convenience macros for printing function arguments in log lines in the
14 // format arg_name=value.
15 #define FORMAT_ARG(arg) " " #arg "=" << arg
16 #define FORMAT_INT_ARG(arg) " " #arg "=" << static_cast<int>(arg)
17 
18 // Convenience macros for printing Spdy*IR attributes in log lines in the
19 // format attrib_name=value.
20 #define FORMAT_ATTR(ir, attrib) " " #attrib "=" << ir.attrib()
21 #define FORMAT_INT_ATTR(ir, attrib) \
22   " " #attrib "=" << static_cast<int>(ir.attrib())
23 
24 namespace {
25 
26 // Logs a container, using a user-provided object to log each individual item.
27 template <typename T, typename ItemLogger>
28 struct ContainerLogger {
ContainerLogger__anon969d02e50111::ContainerLogger29   explicit ContainerLogger(const T& c, ItemLogger l)
30       : container(c), item_logger(l) {}
31 
operator <<(std::ostream & out,const ContainerLogger & logger)32   friend std::ostream& operator<<(std::ostream& out,
33                                   const ContainerLogger& logger) {
34     out << "[";
35     auto begin = logger.container.begin();
36     for (auto it = begin; it != logger.container.end(); ++it) {
37       if (it != begin) {
38         out << ", ";
39       }
40       logger.item_logger.Log(out, *it);
41     }
42     out << "]";
43     return out;
44   }
45   const T& container;
46   ItemLogger item_logger;
47 };
48 
49 // Returns a ContainerLogger that will log |container| using |item_logger|.
50 template <typename T, typename ItemLogger>
LogContainer(const T & container,ItemLogger item_logger)51 auto LogContainer(const T& container, ItemLogger item_logger)
52     -> decltype(ContainerLogger<T, ItemLogger>(container, item_logger)) {
53   return ContainerLogger<T, ItemLogger>(container, item_logger);
54 }
55 
56 }  // anonymous namespace
57 
58 #define FORMAT_HEADER_BLOCK(ir) \
59   " header_block=" << LogContainer(ir.header_block(), LogHeaderBlockEntry())
60 
61 namespace http2 {
62 
63 using spdy::Http2HeaderBlock;
64 using spdy::SettingsMap;
65 using spdy::SpdyAltSvcIR;
66 using spdy::SpdyContinuationIR;
67 using spdy::SpdyDataIR;
68 using spdy::SpdyGoAwayIR;
69 using spdy::SpdyHeadersIR;
70 using spdy::SpdyPingIR;
71 using spdy::SpdyPriorityIR;
72 using spdy::SpdyPushPromiseIR;
73 using spdy::SpdyRstStreamIR;
74 using spdy::SpdySettingsIR;
75 using spdy::SpdyStreamId;
76 using spdy::SpdyUnknownIR;
77 using spdy::SpdyWindowUpdateIR;
78 
79 namespace {
80 
81 // Defines how elements of Http2HeaderBlocks are logged.
82 struct LogHeaderBlockEntry {
Loghttp2::__anon969d02e50211::LogHeaderBlockEntry83   void Log(std::ostream& out,
84            const Http2HeaderBlock::value_type& entry) const {  // NOLINT
85     out << "\"" << entry.first << "\": \"" << entry.second << "\"";
86   }
87 };
88 
89 // Defines how elements of SettingsMap are logged.
90 struct LogSettingsEntry {
Loghttp2::__anon969d02e50211::LogSettingsEntry91   void Log(std::ostream& out,
92            const SettingsMap::value_type& entry) const {  // NOLINT
93     out << spdy::SettingsIdToString(entry.first) << ": " << entry.second;
94   }
95 };
96 
97 // Defines how elements of AlternativeServiceVector are logged.
98 struct LogAlternativeService {
Loghttp2::__anon969d02e50211::LogAlternativeService99   void Log(std::ostream& out,
100            const spdy::SpdyAltSvcWireFormat::AlternativeService& altsvc)
101       const {  // NOLINT
102     out << "{"
103         << "protocol_id=" << altsvc.protocol_id << " host=" << altsvc.host
104         << " port=" << altsvc.port
105         << " max_age_seconds=" << altsvc.max_age_seconds << " version=";
106     for (auto v : altsvc.version) {
107       out << v << ",";
108     }
109     out << "}";
110   }
111 };
112 
113 }  // anonymous namespace
114 
Http2TraceLogger(SpdyFramerVisitorInterface * parent,absl::string_view perspective,std::function<bool ()> is_enabled,const void * connection_id)115 Http2TraceLogger::Http2TraceLogger(SpdyFramerVisitorInterface* parent,
116                                    absl::string_view perspective,
117                                    std::function<bool()> is_enabled,
118                                    const void* connection_id)
119     : wrapped_(parent),
120       perspective_(perspective),
121       is_enabled_(std::move(is_enabled)),
122       connection_id_(connection_id) {}
123 
~Http2TraceLogger()124 Http2TraceLogger::~Http2TraceLogger() {
125   if (recording_headers_handler_ != nullptr &&
126       !recording_headers_handler_->decoded_block().empty()) {
127     HTTP2_TRACE_LOG(perspective_, is_enabled_)
128         << "connection_id=" << connection_id_
129         << " Received headers that were never logged! keys/values:"
130         << recording_headers_handler_->decoded_block().DebugString();
131   }
132 }
133 
OnError(Http2DecoderAdapter::SpdyFramerError error,std::string detailed_error)134 void Http2TraceLogger::OnError(Http2DecoderAdapter::SpdyFramerError error,
135                                std::string detailed_error) {
136   HTTP2_TRACE_LOG(perspective_, is_enabled_)
137       << "OnError:" << FORMAT_ARG(connection_id_)
138       << ", error=" << Http2DecoderAdapter::SpdyFramerErrorToString(error);
139   wrapped_->OnError(error, detailed_error);
140 }
141 
OnCommonHeader(SpdyStreamId stream_id,size_t length,uint8_t type,uint8_t flags)142 void Http2TraceLogger::OnCommonHeader(SpdyStreamId stream_id, size_t length,
143                                       uint8_t type, uint8_t flags) {
144   HTTP2_TRACE_LOG(perspective_, is_enabled_)
145       << "OnCommonHeader:" << FORMAT_ARG(connection_id_)
146       << FORMAT_ARG(stream_id) << FORMAT_ARG(length) << FORMAT_INT_ARG(type)
147       << FORMAT_INT_ARG(flags);
148   wrapped_->OnCommonHeader(stream_id, length, type, flags);
149 }
150 
OnDataFrameHeader(SpdyStreamId stream_id,size_t length,bool fin)151 void Http2TraceLogger::OnDataFrameHeader(SpdyStreamId stream_id, size_t length,
152                                          bool fin) {
153   HTTP2_TRACE_LOG(perspective_, is_enabled_)
154       << "OnDataFrameHeader:" << FORMAT_ARG(connection_id_)
155       << FORMAT_ARG(stream_id) << FORMAT_ARG(length) << FORMAT_ARG(fin);
156   wrapped_->OnDataFrameHeader(stream_id, length, fin);
157 }
158 
OnStreamFrameData(SpdyStreamId stream_id,const char * data,size_t len)159 void Http2TraceLogger::OnStreamFrameData(SpdyStreamId stream_id,
160                                          const char* data, size_t len) {
161   HTTP2_TRACE_LOG(perspective_, is_enabled_)
162       << "OnStreamFrameData:" << FORMAT_ARG(connection_id_)
163       << FORMAT_ARG(stream_id) << FORMAT_ARG(len);
164   wrapped_->OnStreamFrameData(stream_id, data, len);
165 }
166 
OnStreamEnd(SpdyStreamId stream_id)167 void Http2TraceLogger::OnStreamEnd(SpdyStreamId stream_id) {
168   HTTP2_TRACE_LOG(perspective_, is_enabled_)
169       << "OnStreamEnd:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id);
170   wrapped_->OnStreamEnd(stream_id);
171 }
172 
OnStreamPadLength(SpdyStreamId stream_id,size_t value)173 void Http2TraceLogger::OnStreamPadLength(SpdyStreamId stream_id, size_t value) {
174   HTTP2_TRACE_LOG(perspective_, is_enabled_)
175       << "OnStreamPadLength:" << FORMAT_ARG(connection_id_)
176       << FORMAT_ARG(stream_id) << FORMAT_ARG(value);
177   wrapped_->OnStreamPadLength(stream_id, value);
178 }
179 
OnStreamPadding(SpdyStreamId stream_id,size_t len)180 void Http2TraceLogger::OnStreamPadding(SpdyStreamId stream_id, size_t len) {
181   HTTP2_TRACE_LOG(perspective_, is_enabled_)
182       << "OnStreamPadding:" << FORMAT_ARG(connection_id_)
183       << FORMAT_ARG(stream_id) << FORMAT_ARG(len);
184   wrapped_->OnStreamPadding(stream_id, len);
185 }
186 
OnHeaderFrameStart(SpdyStreamId stream_id)187 spdy::SpdyHeadersHandlerInterface* Http2TraceLogger::OnHeaderFrameStart(
188     SpdyStreamId stream_id) {
189   HTTP2_TRACE_LOG(perspective_, is_enabled_)
190       << "OnHeaderFrameStart:" << FORMAT_ARG(connection_id_)
191       << FORMAT_ARG(stream_id);
192   spdy::SpdyHeadersHandlerInterface* result =
193       wrapped_->OnHeaderFrameStart(stream_id);
194   if (is_enabled_()) {
195     recording_headers_handler_ =
196         std::make_unique<spdy::RecordingHeadersHandler>(result);
197     result = recording_headers_handler_.get();
198   } else {
199     recording_headers_handler_ = nullptr;
200   }
201   return result;
202 }
203 
OnHeaderFrameEnd(SpdyStreamId stream_id)204 void Http2TraceLogger::OnHeaderFrameEnd(SpdyStreamId stream_id) {
205   HTTP2_TRACE_LOG(perspective_, is_enabled_)
206       << "OnHeaderFrameEnd:" << FORMAT_ARG(connection_id_)
207       << FORMAT_ARG(stream_id);
208   LogReceivedHeaders();
209   wrapped_->OnHeaderFrameEnd(stream_id);
210   recording_headers_handler_ = nullptr;
211 }
212 
OnRstStream(SpdyStreamId stream_id,SpdyErrorCode error_code)213 void Http2TraceLogger::OnRstStream(SpdyStreamId stream_id,
214                                    SpdyErrorCode error_code) {
215   HTTP2_TRACE_LOG(perspective_, is_enabled_)
216       << "OnRstStream:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
217       << " error_code=" << spdy::ErrorCodeToString(error_code);
218   wrapped_->OnRstStream(stream_id, error_code);
219 }
220 
OnSettings()221 void Http2TraceLogger::OnSettings() { wrapped_->OnSettings(); }
222 
OnSetting(SpdySettingsId id,uint32_t value)223 void Http2TraceLogger::OnSetting(SpdySettingsId id, uint32_t value) {
224   HTTP2_TRACE_LOG(perspective_, is_enabled_)
225       << "OnSetting:" << FORMAT_ARG(connection_id_)
226       << " id=" << spdy::SettingsIdToString(id) << FORMAT_ARG(value);
227   wrapped_->OnSetting(id, value);
228 }
229 
OnSettingsEnd()230 void Http2TraceLogger::OnSettingsEnd() {
231   HTTP2_TRACE_LOG(perspective_, is_enabled_)
232       << "OnSettingsEnd:" << FORMAT_ARG(connection_id_);
233   wrapped_->OnSettingsEnd();
234 }
235 
OnSettingsAck()236 void Http2TraceLogger::OnSettingsAck() {
237   HTTP2_TRACE_LOG(perspective_, is_enabled_)
238       << "OnSettingsAck:" << FORMAT_ARG(connection_id_);
239   wrapped_->OnSettingsAck();
240 }
241 
OnPing(SpdyPingId unique_id,bool is_ack)242 void Http2TraceLogger::OnPing(SpdyPingId unique_id, bool is_ack) {
243   HTTP2_TRACE_LOG(perspective_, is_enabled_)
244       << "OnPing:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(unique_id)
245       << FORMAT_ARG(is_ack);
246   wrapped_->OnPing(unique_id, is_ack);
247 }
248 
OnGoAway(SpdyStreamId last_accepted_stream_id,SpdyErrorCode error_code)249 void Http2TraceLogger::OnGoAway(SpdyStreamId last_accepted_stream_id,
250                                 SpdyErrorCode error_code) {
251   HTTP2_TRACE_LOG(perspective_, is_enabled_)
252       << "OnGoAway:" << FORMAT_ARG(connection_id_)
253       << FORMAT_ARG(last_accepted_stream_id)
254       << " error_code=" << spdy::ErrorCodeToString(error_code);
255   wrapped_->OnGoAway(last_accepted_stream_id, error_code);
256 }
257 
OnGoAwayFrameData(const char * goaway_data,size_t len)258 bool Http2TraceLogger::OnGoAwayFrameData(const char* goaway_data, size_t len) {
259   return wrapped_->OnGoAwayFrameData(goaway_data, len);
260 }
261 
OnHeaders(SpdyStreamId stream_id,size_t payload_length,bool has_priority,int weight,SpdyStreamId parent_stream_id,bool exclusive,bool fin,bool end)262 void Http2TraceLogger::OnHeaders(SpdyStreamId stream_id, size_t payload_length,
263                                  bool has_priority, int weight,
264                                  SpdyStreamId parent_stream_id, bool exclusive,
265                                  bool fin, bool end) {
266   HTTP2_TRACE_LOG(perspective_, is_enabled_)
267       << "OnHeaders:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
268       << FORMAT_ARG(payload_length) << FORMAT_ARG(has_priority)
269       << FORMAT_INT_ARG(weight) << FORMAT_ARG(parent_stream_id)
270       << FORMAT_ARG(exclusive) << FORMAT_ARG(fin) << FORMAT_ARG(end);
271   wrapped_->OnHeaders(stream_id, payload_length, has_priority, weight,
272                       parent_stream_id, exclusive, fin, end);
273 }
274 
OnWindowUpdate(SpdyStreamId stream_id,int delta_window_size)275 void Http2TraceLogger::OnWindowUpdate(SpdyStreamId stream_id,
276                                       int delta_window_size) {
277   HTTP2_TRACE_LOG(perspective_, is_enabled_)
278       << "OnWindowUpdate:" << FORMAT_ARG(connection_id_)
279       << FORMAT_ARG(stream_id) << FORMAT_ARG(delta_window_size);
280   wrapped_->OnWindowUpdate(stream_id, delta_window_size);
281 }
282 
OnPushPromise(SpdyStreamId original_stream_id,SpdyStreamId promised_stream_id,bool end)283 void Http2TraceLogger::OnPushPromise(SpdyStreamId original_stream_id,
284                                      SpdyStreamId promised_stream_id,
285                                      bool end) {
286   HTTP2_TRACE_LOG(perspective_, is_enabled_)
287       << "OnPushPromise:" << FORMAT_ARG(connection_id_)
288       << FORMAT_ARG(original_stream_id) << FORMAT_ARG(promised_stream_id)
289       << FORMAT_ARG(end);
290   wrapped_->OnPushPromise(original_stream_id, promised_stream_id, end);
291 }
292 
OnContinuation(SpdyStreamId stream_id,size_t payload_length,bool end)293 void Http2TraceLogger::OnContinuation(SpdyStreamId stream_id,
294                                       size_t payload_length, bool end) {
295   HTTP2_TRACE_LOG(perspective_, is_enabled_)
296       << "OnContinuation:" << FORMAT_ARG(connection_id_)
297       << FORMAT_ARG(stream_id) << FORMAT_ARG(payload_length) << FORMAT_ARG(end);
298   wrapped_->OnContinuation(stream_id, payload_length, end);
299 }
300 
OnAltSvc(SpdyStreamId stream_id,absl::string_view origin,const SpdyAltSvcWireFormat::AlternativeServiceVector & altsvc_vector)301 void Http2TraceLogger::OnAltSvc(
302     SpdyStreamId stream_id, absl::string_view origin,
303     const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) {
304   HTTP2_TRACE_LOG(perspective_, is_enabled_)
305       << "OnAltSvc:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
306       << FORMAT_ARG(origin) << " altsvc_vector="
307       << LogContainer(altsvc_vector, LogAlternativeService());
308   wrapped_->OnAltSvc(stream_id, origin, altsvc_vector);
309 }
310 
OnPriority(SpdyStreamId stream_id,SpdyStreamId parent_stream_id,int weight,bool exclusive)311 void Http2TraceLogger::OnPriority(SpdyStreamId stream_id,
312                                   SpdyStreamId parent_stream_id, int weight,
313                                   bool exclusive) {
314   HTTP2_TRACE_LOG(perspective_, is_enabled_)
315       << "OnPriority:" << FORMAT_ARG(connection_id_) << FORMAT_ARG(stream_id)
316       << FORMAT_ARG(parent_stream_id) << FORMAT_INT_ARG(weight)
317       << FORMAT_ARG(exclusive);
318   wrapped_->OnPriority(stream_id, parent_stream_id, weight, exclusive);
319 }
320 
OnPriorityUpdate(SpdyStreamId prioritized_stream_id,absl::string_view priority_field_value)321 void Http2TraceLogger::OnPriorityUpdate(
322     SpdyStreamId prioritized_stream_id,
323     absl::string_view priority_field_value) {
324   HTTP2_TRACE_LOG(perspective_, is_enabled_)
325       << "OnPriorityUpdate:" << FORMAT_ARG(connection_id_)
326       << FORMAT_ARG(prioritized_stream_id) << FORMAT_ARG(priority_field_value);
327   wrapped_->OnPriorityUpdate(prioritized_stream_id, priority_field_value);
328 }
329 
OnUnknownFrame(SpdyStreamId stream_id,uint8_t frame_type)330 bool Http2TraceLogger::OnUnknownFrame(SpdyStreamId stream_id,
331                                       uint8_t frame_type) {
332   HTTP2_TRACE_LOG(perspective_, is_enabled_)
333       << "OnUnknownFrame:" << FORMAT_ARG(connection_id_)
334       << FORMAT_ARG(stream_id) << FORMAT_INT_ARG(frame_type);
335   return wrapped_->OnUnknownFrame(stream_id, frame_type);
336 }
337 
OnUnknownFrameStart(spdy::SpdyStreamId stream_id,size_t length,uint8_t type,uint8_t flags)338 void Http2TraceLogger::OnUnknownFrameStart(spdy::SpdyStreamId stream_id,
339                                            size_t length, uint8_t type,
340                                            uint8_t flags) {
341   HTTP2_TRACE_LOG(perspective_, is_enabled_)
342       << "OnUnknownFrameStart:" << FORMAT_ARG(connection_id_)
343       << FORMAT_ARG(stream_id) << FORMAT_ARG(length) << FORMAT_INT_ARG(type)
344       << FORMAT_INT_ARG(flags);
345   wrapped_->OnUnknownFrameStart(stream_id, length, type, flags);
346 }
347 
OnUnknownFramePayload(spdy::SpdyStreamId stream_id,absl::string_view payload)348 void Http2TraceLogger::OnUnknownFramePayload(spdy::SpdyStreamId stream_id,
349                                              absl::string_view payload) {
350   HTTP2_TRACE_LOG(perspective_, is_enabled_)
351       << "OnUnknownFramePayload:" << FORMAT_ARG(connection_id_)
352       << FORMAT_ARG(stream_id) << " length=" << payload.size();
353   wrapped_->OnUnknownFramePayload(stream_id, payload);
354 }
355 
LogReceivedHeaders() const356 void Http2TraceLogger::LogReceivedHeaders() const {
357   if (recording_headers_handler_ == nullptr) {
358     // Trace logging was not enabled when the start of the header block was
359     // received.
360     return;
361   }
362   HTTP2_TRACE_LOG(perspective_, is_enabled_)
363       << "Received headers;" << FORMAT_ARG(connection_id_) << " keys/values:"
364       << recording_headers_handler_->decoded_block().DebugString()
365       << " compressed_bytes="
366       << recording_headers_handler_->compressed_header_bytes()
367       << " uncompressed_bytes="
368       << recording_headers_handler_->uncompressed_header_bytes();
369 }
370 
VisitRstStream(const SpdyRstStreamIR & rst_stream)371 void Http2FrameLogger::VisitRstStream(const SpdyRstStreamIR& rst_stream) {
372   HTTP2_TRACE_LOG(perspective_, is_enabled_)
373       << "Wrote SpdyRstStreamIR:" << FORMAT_ARG(connection_id_)
374       << FORMAT_ATTR(rst_stream, stream_id)
375       << " error_code=" << spdy::ErrorCodeToString(rst_stream.error_code());
376 }
377 
VisitSettings(const SpdySettingsIR & settings)378 void Http2FrameLogger::VisitSettings(const SpdySettingsIR& settings) {
379   HTTP2_TRACE_LOG(perspective_, is_enabled_)
380       << "Wrote SpdySettingsIR:" << FORMAT_ARG(connection_id_)
381       << FORMAT_ATTR(settings, is_ack)
382       << " values=" << LogContainer(settings.values(), LogSettingsEntry());
383 }
384 
VisitPing(const SpdyPingIR & ping)385 void Http2FrameLogger::VisitPing(const SpdyPingIR& ping) {
386   HTTP2_TRACE_LOG(perspective_, is_enabled_)
387       << "Wrote SpdyPingIR:" << FORMAT_ARG(connection_id_)
388       << FORMAT_ATTR(ping, id) << FORMAT_ATTR(ping, is_ack);
389 }
390 
VisitGoAway(const SpdyGoAwayIR & goaway)391 void Http2FrameLogger::VisitGoAway(const SpdyGoAwayIR& goaway) {
392   HTTP2_TRACE_LOG(perspective_, is_enabled_)
393       << "Wrote SpdyGoAwayIR:" << FORMAT_ARG(connection_id_)
394       << FORMAT_ATTR(goaway, last_good_stream_id)
395       << " error_code=" << spdy::ErrorCodeToString(goaway.error_code())
396       << FORMAT_ATTR(goaway, description);
397 }
398 
VisitHeaders(const SpdyHeadersIR & headers)399 void Http2FrameLogger::VisitHeaders(const SpdyHeadersIR& headers) {
400   HTTP2_TRACE_LOG(perspective_, is_enabled_)
401       << "Wrote SpdyHeadersIR:" << FORMAT_ARG(connection_id_)
402       << FORMAT_ATTR(headers, stream_id) << FORMAT_ATTR(headers, fin)
403       << FORMAT_ATTR(headers, has_priority) << FORMAT_INT_ATTR(headers, weight)
404       << FORMAT_ATTR(headers, parent_stream_id)
405       << FORMAT_ATTR(headers, exclusive) << FORMAT_ATTR(headers, padded)
406       << FORMAT_ATTR(headers, padding_payload_len)
407       << FORMAT_HEADER_BLOCK(headers);
408 }
409 
VisitWindowUpdate(const SpdyWindowUpdateIR & window_update)410 void Http2FrameLogger::VisitWindowUpdate(
411     const SpdyWindowUpdateIR& window_update) {
412   HTTP2_TRACE_LOG(perspective_, is_enabled_)
413       << "Wrote SpdyWindowUpdateIR:" << FORMAT_ARG(connection_id_)
414       << FORMAT_ATTR(window_update, stream_id)
415       << FORMAT_ATTR(window_update, delta);
416 }
417 
VisitPushPromise(const SpdyPushPromiseIR & push_promise)418 void Http2FrameLogger::VisitPushPromise(const SpdyPushPromiseIR& push_promise) {
419   HTTP2_TRACE_LOG(perspective_, is_enabled_)
420       << "Wrote SpdyPushPromiseIR:" << FORMAT_ARG(connection_id_)
421       << FORMAT_ATTR(push_promise, stream_id) << FORMAT_ATTR(push_promise, fin)
422       << FORMAT_ATTR(push_promise, promised_stream_id)
423       << FORMAT_ATTR(push_promise, padded)
424       << FORMAT_ATTR(push_promise, padding_payload_len)
425       << FORMAT_HEADER_BLOCK(push_promise);
426 }
427 
VisitContinuation(const SpdyContinuationIR & continuation)428 void Http2FrameLogger::VisitContinuation(
429     const SpdyContinuationIR& continuation) {
430   HTTP2_TRACE_LOG(perspective_, is_enabled_)
431       << "Wrote SpdyContinuationIR:" << FORMAT_ARG(connection_id_)
432       << FORMAT_ATTR(continuation, stream_id)
433       << FORMAT_ATTR(continuation, end_headers);
434 }
435 
VisitAltSvc(const SpdyAltSvcIR & altsvc)436 void Http2FrameLogger::VisitAltSvc(const SpdyAltSvcIR& altsvc) {
437   HTTP2_TRACE_LOG(perspective_, is_enabled_)
438       << "Wrote SpdyAltSvcIR:" << FORMAT_ARG(connection_id_)
439       << FORMAT_ATTR(altsvc, stream_id) << FORMAT_ATTR(altsvc, origin)
440       << " altsvc_vector="
441       << LogContainer(altsvc.altsvc_vector(), LogAlternativeService());
442 }
443 
VisitPriority(const SpdyPriorityIR & priority)444 void Http2FrameLogger::VisitPriority(const SpdyPriorityIR& priority) {
445   HTTP2_TRACE_LOG(perspective_, is_enabled_)
446       << "Wrote SpdyPriorityIR:" << FORMAT_ARG(connection_id_)
447       << FORMAT_ATTR(priority, stream_id)
448       << FORMAT_ATTR(priority, parent_stream_id)
449       << FORMAT_INT_ATTR(priority, weight) << FORMAT_ATTR(priority, exclusive);
450 }
451 
VisitData(const SpdyDataIR & data)452 void Http2FrameLogger::VisitData(const SpdyDataIR& data) {
453   HTTP2_TRACE_LOG(perspective_, is_enabled_)
454       << "Wrote SpdyDataIR:" << FORMAT_ARG(connection_id_)
455       << FORMAT_ATTR(data, stream_id) << FORMAT_ATTR(data, fin)
456       << " data_len=" << data.data_len() << FORMAT_ATTR(data, padded)
457       << FORMAT_ATTR(data, padding_payload_len);
458 }
459 
VisitPriorityUpdate(const spdy::SpdyPriorityUpdateIR & priority_update)460 void Http2FrameLogger::VisitPriorityUpdate(
461     const spdy::SpdyPriorityUpdateIR& priority_update) {
462   HTTP2_TRACE_LOG(perspective_, is_enabled_)
463       << "Wrote SpdyPriorityUpdateIR:" << FORMAT_ARG(connection_id_)
464       << FORMAT_ATTR(priority_update, stream_id)
465       << FORMAT_ATTR(priority_update, prioritized_stream_id)
466       << FORMAT_ATTR(priority_update, priority_field_value);
467 }
468 
VisitAcceptCh(const spdy::SpdyAcceptChIR &)469 void Http2FrameLogger::VisitAcceptCh(
470     const spdy::SpdyAcceptChIR& /*accept_ch*/) {
471   QUICHE_BUG(bug_2794_2)
472       << "Sending ACCEPT_CH frames is currently unimplemented.";
473 }
474 
VisitUnknown(const SpdyUnknownIR & ir)475 void Http2FrameLogger::VisitUnknown(const SpdyUnknownIR& ir) {
476   HTTP2_TRACE_LOG(perspective_, is_enabled_)
477       << "Wrote SpdyUnknownIR:" << FORMAT_ARG(connection_id_)
478       << FORMAT_ATTR(ir, stream_id) << FORMAT_INT_ATTR(ir, type)
479       << FORMAT_INT_ATTR(ir, flags) << FORMAT_ATTR(ir, length);
480 }
481 
482 }  // namespace http2
483