OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef NET_TOOLS_BALSA_BALSA_HEADERS_H_ | 5 #ifndef NET_TOOLS_BALSA_BALSA_HEADERS_H_ |
6 #define NET_TOOLS_BALSA_BALSA_HEADERS_H_ | 6 #define NET_TOOLS_BALSA_BALSA_HEADERS_H_ |
7 | 7 |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <iosfwd> | 9 #include <iosfwd> |
10 #include <iterator> | 10 #include <iterator> |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 // The BufferBlock is a structure used internally by the | 69 // The BufferBlock is a structure used internally by the |
70 // BalsaBuffer class to store the base buffer pointers to | 70 // BalsaBuffer class to store the base buffer pointers to |
71 // each block, as well as the important metadata for buffer | 71 // each block, as well as the important metadata for buffer |
72 // sizes and bytes free. | 72 // sizes and bytes free. |
73 struct BufferBlock { | 73 struct BufferBlock { |
74 public: | 74 public: |
75 char* buffer; | 75 char* buffer; |
76 size_t buffer_size; | 76 size_t buffer_size; |
77 size_t bytes_free; | 77 size_t bytes_free; |
78 | 78 |
79 size_t bytes_used() const { | 79 size_t bytes_used() const { return buffer_size - bytes_free; } |
80 return buffer_size - bytes_free; | 80 char* start_of_unused_bytes() const { return buffer + bytes_used(); } |
81 } | |
82 char* start_of_unused_bytes() const { | |
83 return buffer + bytes_used(); | |
84 } | |
85 | 81 |
86 BufferBlock() : buffer(NULL), buffer_size(0), bytes_free(0) {} | 82 BufferBlock() : buffer(NULL), buffer_size(0), bytes_free(0) {} |
87 ~BufferBlock() {} | 83 ~BufferBlock() {} |
88 | 84 |
89 BufferBlock(char* buf, size_t size, size_t free) : | 85 BufferBlock(char* buf, size_t size, size_t free) |
90 buffer(buf), buffer_size(size), bytes_free(free) {} | 86 : buffer(buf), buffer_size(size), bytes_free(free) {} |
91 // Yes we want this to be copyable (it gets stuck into vectors). | 87 // Yes we want this to be copyable (it gets stuck into vectors). |
92 // For this reason, we don't use scoped ptrs, etc. here-- it | 88 // For this reason, we don't use scoped ptrs, etc. here-- it |
93 // is more efficient to manage this memory externally to this | 89 // is more efficient to manage this memory externally to this |
94 // object. | 90 // object. |
95 }; | 91 }; |
96 | 92 |
97 typedef std::vector<BufferBlock> Blocks; | 93 typedef std::vector<BufferBlock> Blocks; |
98 | 94 |
99 ~BalsaBuffer(); | 95 ~BalsaBuffer(); |
100 | 96 |
101 // Returns the total amount of memory used by the buffer blocks. | 97 // Returns the total amount of memory used by the buffer blocks. |
102 size_t GetTotalBufferBlockSize() const; | 98 size_t GetTotalBufferBlockSize() const; |
103 | 99 |
104 const char* GetPtr(Blocks::size_type block_idx) const { | 100 const char* GetPtr(Blocks::size_type block_idx) const { |
105 DCHECK_LT(block_idx, blocks_.size()) | 101 DCHECK_LT(block_idx, blocks_.size()) << block_idx << ", " << blocks_.size(); |
106 << block_idx << ", " << blocks_.size(); | |
107 return blocks_[block_idx].buffer; | 102 return blocks_[block_idx].buffer; |
108 } | 103 } |
109 | 104 |
110 char* GetPtr(Blocks::size_type block_idx) { | 105 char* GetPtr(Blocks::size_type block_idx) { |
111 DCHECK_LT(block_idx, blocks_.size()) | 106 DCHECK_LT(block_idx, blocks_.size()) << block_idx << ", " << blocks_.size(); |
112 << block_idx << ", " << blocks_.size(); | |
113 return blocks_[block_idx].buffer; | 107 return blocks_[block_idx].buffer; |
114 } | 108 } |
115 | 109 |
116 // This function is different from Write(), as it ensures that the data | 110 // This function is different from Write(), as it ensures that the data |
117 // stored via subsequent calls to this function are all contiguous (and in | 111 // stored via subsequent calls to this function are all contiguous (and in |
118 // the order in which these writes happened). This is essentially the same | 112 // the order in which these writes happened). This is essentially the same |
119 // as a string append. | 113 // as a string append. |
120 // | 114 // |
121 // You may call this function at any time between object | 115 // You may call this function at any time between object |
122 // construction/Clear(), and the calling of the | 116 // construction/Clear(), and the calling of the |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 // NoMoreWriteToContiguousBuffer function has been called since the last | 149 // NoMoreWriteToContiguousBuffer function has been called since the last |
156 // Clear/Construction. | 150 // Clear/Construction. |
157 char* Reserve(size_t size, Blocks::size_type* block_buffer_idx); | 151 char* Reserve(size_t size, Blocks::size_type* block_buffer_idx); |
158 | 152 |
159 void Clear(); | 153 void Clear(); |
160 | 154 |
161 void Swap(BalsaBuffer* b); | 155 void Swap(BalsaBuffer* b); |
162 | 156 |
163 void CopyFrom(const BalsaBuffer& b); | 157 void CopyFrom(const BalsaBuffer& b); |
164 | 158 |
165 const char* StartOfFirstBlock() const { | 159 const char* StartOfFirstBlock() const { return blocks_[0].buffer; } |
166 return blocks_[0].buffer; | |
167 } | |
168 | 160 |
169 const char* EndOfFirstBlock() const { | 161 const char* EndOfFirstBlock() const { |
170 return blocks_[0].buffer + blocks_[0].bytes_used(); | 162 return blocks_[0].buffer + blocks_[0].bytes_used(); |
171 } | 163 } |
172 | 164 |
173 bool can_write_to_contiguous_buffer() const { | 165 bool can_write_to_contiguous_buffer() const { |
174 return can_write_to_contiguous_buffer_; | 166 return can_write_to_contiguous_buffer_; |
175 } | 167 } |
176 size_t blocksize() const { return blocksize_; } | 168 size_t blocksize() const { return blocksize_; } |
177 Blocks::size_type num_blocks() const { return blocks_.size(); } | 169 Blocks::size_type num_blocks() const { return blocks_.size(); } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 // erased() or modified should be valid until the object is cleared or | 232 // erased() or modified should be valid until the object is cleared or |
241 // destroyed. | 233 // destroyed. |
242 | 234 |
243 class BalsaHeaders { | 235 class BalsaHeaders { |
244 public: | 236 public: |
245 struct HeaderLineDescription { | 237 struct HeaderLineDescription { |
246 HeaderLineDescription(size_t first_character_index, | 238 HeaderLineDescription(size_t first_character_index, |
247 size_t key_end_index, | 239 size_t key_end_index, |
248 size_t value_begin_index, | 240 size_t value_begin_index, |
249 size_t last_character_index, | 241 size_t last_character_index, |
250 size_t buffer_base_index) : | 242 size_t buffer_base_index) |
251 first_char_idx(first_character_index), | 243 : first_char_idx(first_character_index), |
252 key_end_idx(key_end_index), | 244 key_end_idx(key_end_index), |
253 value_begin_idx(value_begin_index), | 245 value_begin_idx(value_begin_index), |
254 last_char_idx(last_character_index), | 246 last_char_idx(last_character_index), |
255 buffer_base_idx(buffer_base_index), | 247 buffer_base_idx(buffer_base_index), |
256 skip(false) {} | 248 skip(false) {} |
257 | 249 |
258 HeaderLineDescription() : | 250 HeaderLineDescription() |
259 first_char_idx(0), | 251 : first_char_idx(0), |
260 key_end_idx(0), | 252 key_end_idx(0), |
261 value_begin_idx(0), | 253 value_begin_idx(0), |
262 last_char_idx(0), | 254 last_char_idx(0), |
263 buffer_base_idx(0), | 255 buffer_base_idx(0), |
264 skip(false) {} | 256 skip(false) {} |
265 | 257 |
266 size_t first_char_idx; | 258 size_t first_char_idx; |
267 size_t key_end_idx; | 259 size_t key_end_idx; |
268 size_t value_begin_idx; | 260 size_t value_begin_idx; |
269 size_t last_char_idx; | 261 size_t last_char_idx; |
270 BalsaBuffer::Blocks::size_type buffer_base_idx; | 262 BalsaBuffer::Blocks::size_type buffer_base_idx; |
271 bool skip; | 263 bool skip; |
272 }; | 264 }; |
273 | 265 |
274 typedef std::vector<base::StringPiece> HeaderTokenList; | 266 typedef std::vector<base::StringPiece> HeaderTokenList; |
(...skipping 30 matching lines...) Expand all Loading... |
305 typedef ptrdiff_t difference_type; | 297 typedef ptrdiff_t difference_type; |
306 | 298 |
307 typedef iterator_base self; | 299 typedef iterator_base self; |
308 | 300 |
309 // default constructor. | 301 // default constructor. |
310 iterator_base(); | 302 iterator_base(); |
311 | 303 |
312 // copy constructor. | 304 // copy constructor. |
313 iterator_base(const iterator_base& it); | 305 iterator_base(const iterator_base& it); |
314 | 306 |
315 reference operator*() const { | 307 reference operator*() const { return Lookup(idx_); } |
316 return Lookup(idx_); | |
317 } | |
318 | 308 |
319 pointer operator->() const { | 309 pointer operator->() const { return &(this->operator*()); } |
320 return &(this->operator*()); | |
321 } | |
322 | 310 |
323 bool operator==(const self& it) const { | 311 bool operator==(const self& it) const { return idx_ == it.idx_; } |
324 return idx_ == it.idx_; | |
325 } | |
326 | 312 |
327 bool operator<(const self& it) const { | 313 bool operator<(const self& it) const { return idx_ < it.idx_; } |
328 return idx_ < it.idx_; | |
329 } | |
330 | 314 |
331 bool operator<=(const self& it) const { | 315 bool operator<=(const self& it) const { return idx_ <= it.idx_; } |
332 return idx_ <= it.idx_; | |
333 } | |
334 | 316 |
335 bool operator!=(const self& it) const { | 317 bool operator!=(const self& it) const { return !(*this == it); } |
336 return !(*this == it); | |
337 } | |
338 | 318 |
339 bool operator>(const self& it) const { | 319 bool operator>(const self& it) const { return it < *this; } |
340 return it < *this; | |
341 } | |
342 | 320 |
343 bool operator>=(const self& it) const { | 321 bool operator>=(const self& it) const { return it <= *this; } |
344 return it <= *this; | |
345 } | |
346 | 322 |
347 // This mainly exists so that we can have interesting output for | 323 // This mainly exists so that we can have interesting output for |
348 // unittesting. The EXPECT_EQ, EXPECT_NE functions require that | 324 // unittesting. The EXPECT_EQ, EXPECT_NE functions require that |
349 // operator<< work for the classes it sees. It would be better if there | 325 // operator<< work for the classes it sees. It would be better if there |
350 // was an additional traits-like system for the gUnit output... but oh | 326 // was an additional traits-like system for the gUnit output... but oh |
351 // well. | 327 // well. |
352 std::ostream& operator<<(std::ostream& os) const; | 328 std::ostream& operator<<(std::ostream& os) const; |
353 | 329 |
354 protected: | 330 protected: |
355 iterator_base(const BalsaHeaders* headers, HeaderLines::size_type index); | 331 iterator_base(const BalsaHeaders* headers, HeaderLines::size_type index); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
389 idx_ = original_idx - 1; | 365 idx_ = original_idx - 1; |
390 } | 366 } |
391 } | 367 } |
392 | 368 |
393 reference Lookup(HeaderLines::size_type index) const { | 369 reference Lookup(HeaderLines::size_type index) const { |
394 DCHECK_LT(index, headers_->header_lines_.size()); | 370 DCHECK_LT(index, headers_->header_lines_.size()); |
395 const HeaderLineDescription& line = headers_->header_lines_[index]; | 371 const HeaderLineDescription& line = headers_->header_lines_[index]; |
396 const char* stream_begin = headers_->GetPtr(line.buffer_base_idx); | 372 const char* stream_begin = headers_->GetPtr(line.buffer_base_idx); |
397 value_ = value_type( | 373 value_ = value_type( |
398 base::StringPiece(stream_begin + line.first_char_idx, | 374 base::StringPiece(stream_begin + line.first_char_idx, |
399 line.key_end_idx - line.first_char_idx), | 375 line.key_end_idx - line.first_char_idx), |
400 base::StringPiece(stream_begin + line.value_begin_idx, | 376 base::StringPiece(stream_begin + line.value_begin_idx, |
401 line.last_char_idx - line.value_begin_idx)); | 377 line.last_char_idx - line.value_begin_idx)); |
402 DCHECK_GE(line.key_end_idx, line.first_char_idx); | 378 DCHECK_GE(line.key_end_idx, line.first_char_idx); |
403 DCHECK_GE(line.last_char_idx, line.value_begin_idx); | 379 DCHECK_GE(line.last_char_idx, line.value_begin_idx); |
404 return value_; | 380 return value_; |
405 } | 381 } |
406 | 382 |
407 const BalsaHeaders* headers_; | 383 const BalsaHeaders* headers_; |
408 HeaderLines::size_type idx_; | 384 HeaderLines::size_type idx_; |
409 mutable StringPiecePair value_; | 385 mutable StringPiecePair value_; |
410 }; | 386 }; |
411 | 387 |
412 class reverse_iterator_base : public iterator_base { | 388 class reverse_iterator_base : public iterator_base { |
413 public: | 389 public: |
414 typedef reverse_iterator_base self; | 390 typedef reverse_iterator_base self; |
415 typedef iterator_base::reference reference; | 391 typedef iterator_base::reference reference; |
416 typedef iterator_base::pointer pointer; | 392 typedef iterator_base::pointer pointer; |
417 using iterator_base::headers_; | 393 using iterator_base::headers_; |
418 using iterator_base::idx_; | 394 using iterator_base::idx_; |
419 | 395 |
420 reverse_iterator_base() : iterator_base() {} | 396 reverse_iterator_base() : iterator_base() {} |
421 | 397 |
422 // This constructor is no explicit purposely. | 398 // This constructor is no explicit purposely. |
423 reverse_iterator_base(const iterator_base& it) : // NOLINT | 399 reverse_iterator_base(const iterator_base& it) |
424 iterator_base(it) { | 400 : // NOLINT |
425 } | 401 iterator_base(it) {} |
426 | 402 |
427 self& operator=(const iterator_base& it) { | 403 self& operator=(const iterator_base& it) { |
428 idx_ = it.idx_; | 404 idx_ = it.idx_; |
429 headers_ = it.headers_; | 405 headers_ = it.headers_; |
430 return *this; | 406 return *this; |
431 } | 407 } |
432 | 408 |
433 self& operator=(const reverse_iterator_base& it) { | 409 self& operator=(const reverse_iterator_base& it) { |
434 idx_ = it.idx_; | 410 idx_ = it.idx_; |
435 headers_ = it.headers_; | 411 headers_ = it.headers_; |
436 return *this; | 412 return *this; |
437 } | 413 } |
438 | 414 |
439 reference operator*() const { | 415 reference operator*() const { return Lookup(idx_ - 1); } |
440 return Lookup(idx_ - 1); | |
441 } | |
442 | 416 |
443 pointer operator->() const { | 417 pointer operator->() const { return &(this->operator*()); } |
444 return &(this->operator*()); | |
445 } | |
446 | 418 |
447 reverse_iterator_base(const reverse_iterator_base& it) : | 419 reverse_iterator_base(const reverse_iterator_base& it) |
448 iterator_base(it) { } | 420 : iterator_base(it) {} |
449 | 421 |
450 protected: | 422 protected: |
451 void increment() { | 423 void increment() { |
452 --idx_; | 424 --idx_; |
453 iterator_base::decrement(); | 425 iterator_base::decrement(); |
454 ++idx_; | 426 ++idx_; |
455 } | 427 } |
456 | 428 |
457 void decrement() { | 429 void decrement() { |
458 ++idx_; | 430 ++idx_; |
459 iterator_base::increment(); | 431 iterator_base::increment(); |
460 --idx_; | 432 --idx_; |
461 } | 433 } |
462 | 434 |
463 reverse_iterator_base(const BalsaHeaders* headers, | 435 reverse_iterator_base(const BalsaHeaders* headers, |
464 HeaderLines::size_type index) : | 436 HeaderLines::size_type index) |
465 iterator_base(headers, index) {} | 437 : iterator_base(headers, index) {} |
466 }; | 438 }; |
467 | 439 |
468 public: | 440 public: |
469 class const_header_lines_iterator : public iterator_base { | 441 class const_header_lines_iterator : public iterator_base { |
470 friend class BalsaHeaders; | 442 friend class BalsaHeaders; |
| 443 |
471 public: | 444 public: |
472 typedef const_header_lines_iterator self; | 445 typedef const_header_lines_iterator self; |
473 const_header_lines_iterator() : iterator_base() {} | 446 const_header_lines_iterator() : iterator_base() {} |
474 | 447 |
475 const_header_lines_iterator(const const_header_lines_iterator& it) : | 448 const_header_lines_iterator(const const_header_lines_iterator& it) |
476 iterator_base(it.headers_, it.idx_) {} | 449 : iterator_base(it.headers_, it.idx_) {} |
477 | 450 |
478 self& operator++() { | 451 self& operator++() { |
479 iterator_base::increment(); | 452 iterator_base::increment(); |
480 return *this; | 453 return *this; |
481 } | 454 } |
482 | 455 |
483 self& operator--() { | 456 self& operator--() { |
484 iterator_base::decrement(); | 457 iterator_base::decrement(); |
485 return *this; | 458 return *this; |
486 } | 459 } |
| 460 |
487 protected: | 461 protected: |
488 const_header_lines_iterator(const BalsaHeaders* headers, | 462 const_header_lines_iterator(const BalsaHeaders* headers, |
489 HeaderLines::size_type index) : | 463 HeaderLines::size_type index) |
490 iterator_base(headers, index) {} | 464 : iterator_base(headers, index) {} |
491 }; | 465 }; |
492 | 466 |
493 class const_reverse_header_lines_iterator : public reverse_iterator_base { | 467 class const_reverse_header_lines_iterator : public reverse_iterator_base { |
494 public: | 468 public: |
495 typedef const_reverse_header_lines_iterator self; | 469 typedef const_reverse_header_lines_iterator self; |
496 const_reverse_header_lines_iterator() : reverse_iterator_base() {} | 470 const_reverse_header_lines_iterator() : reverse_iterator_base() {} |
497 | 471 |
498 const_reverse_header_lines_iterator( | 472 const_reverse_header_lines_iterator(const const_header_lines_iterator& it) |
499 const const_header_lines_iterator& it) : | 473 : reverse_iterator_base(it.headers_, it.idx_) {} |
500 reverse_iterator_base(it.headers_, it.idx_) {} | |
501 | 474 |
502 const_reverse_header_lines_iterator( | 475 const_reverse_header_lines_iterator( |
503 const const_reverse_header_lines_iterator& it) : | 476 const const_reverse_header_lines_iterator& it) |
504 reverse_iterator_base(it.headers_, it.idx_) {} | 477 : reverse_iterator_base(it.headers_, it.idx_) {} |
505 | 478 |
506 const_header_lines_iterator base() { | 479 const_header_lines_iterator base() { |
507 return const_header_lines_iterator(headers_, idx_); | 480 return const_header_lines_iterator(headers_, idx_); |
508 } | 481 } |
509 | 482 |
510 self& operator++() { | 483 self& operator++() { |
511 reverse_iterator_base::increment(); | 484 reverse_iterator_base::increment(); |
512 return *this; | 485 return *this; |
513 } | 486 } |
514 | 487 |
515 self& operator--() { | 488 self& operator--() { |
516 reverse_iterator_base::decrement(); | 489 reverse_iterator_base::decrement(); |
517 return *this; | 490 return *this; |
518 } | 491 } |
| 492 |
519 protected: | 493 protected: |
520 const_reverse_header_lines_iterator(const BalsaHeaders* headers, | 494 const_reverse_header_lines_iterator(const BalsaHeaders* headers, |
521 HeaderLines::size_type index) : | 495 HeaderLines::size_type index) |
522 reverse_iterator_base(headers, index) {} | 496 : reverse_iterator_base(headers, index) {} |
523 | 497 |
524 friend class BalsaHeaders; | 498 friend class BalsaHeaders; |
525 }; | 499 }; |
526 | 500 |
527 // An iterator that only stops at lines with a particular key. | 501 // An iterator that only stops at lines with a particular key. |
528 // See also GetIteratorForKey. | 502 // See also GetIteratorForKey. |
529 // | 503 // |
530 // Check against header_lines_key_end() to determine when iteration is | 504 // Check against header_lines_key_end() to determine when iteration is |
531 // finished. header_lines_end() will also work. | 505 // finished. header_lines_end() will also work. |
532 class const_header_lines_key_iterator : public iterator_base { | 506 class const_header_lines_key_iterator : public iterator_base { |
533 friend class BalsaHeaders; | 507 friend class BalsaHeaders; |
| 508 |
534 public: | 509 public: |
535 typedef const_header_lines_key_iterator self; | 510 typedef const_header_lines_key_iterator self; |
536 const_header_lines_key_iterator(const const_header_lines_key_iterator&); | 511 const_header_lines_key_iterator(const const_header_lines_key_iterator&); |
537 | 512 |
538 self& operator++() { | 513 self& operator++() { |
539 do { | 514 do { |
540 iterator_base::increment(); | 515 iterator_base::increment(); |
541 } while (!AtEnd() && | 516 } while (!AtEnd() && |
542 !StringPieceUtils::EqualIgnoreCase(key_, (**this).first)); | 517 !StringPieceUtils::EqualIgnoreCase(key_, (**this).first)); |
543 return *this; | 518 return *this; |
544 } | 519 } |
545 | 520 |
546 void operator++(int ignore) { | 521 void operator++(int ignore) { ++(*this); } |
547 ++(*this); | |
548 } | |
549 | 522 |
550 // Only forward-iteration makes sense, so no operator-- defined. | 523 // Only forward-iteration makes sense, so no operator-- defined. |
551 | 524 |
552 private: | 525 private: |
553 const_header_lines_key_iterator(const BalsaHeaders* headers, | 526 const_header_lines_key_iterator(const BalsaHeaders* headers, |
554 HeaderLines::size_type index, | 527 HeaderLines::size_type index, |
555 const base::StringPiece& key); | 528 const base::StringPiece& key); |
556 | 529 |
557 // Should only be used for creating an end iterator. | 530 // Should only be used for creating an end iterator. |
558 const_header_lines_key_iterator(const BalsaHeaders* headers, | 531 const_header_lines_key_iterator(const BalsaHeaders* headers, |
559 HeaderLines::size_type index); | 532 HeaderLines::size_type index); |
560 | 533 |
561 bool AtEnd() const { | 534 bool AtEnd() const { return *this >= headers_->header_lines_end(); } |
562 return *this >= headers_->header_lines_end(); | |
563 } | |
564 | 535 |
565 base::StringPiece key_; | 536 base::StringPiece key_; |
566 }; | 537 }; |
567 | 538 |
568 // TODO(fenix): Revisit the amount of bytes initially allocated to the second | 539 // TODO(fenix): Revisit the amount of bytes initially allocated to the second |
569 // block of the balsa_buffer_. It may make sense to pre-allocate some amount | 540 // block of the balsa_buffer_. It may make sense to pre-allocate some amount |
570 // (roughly the amount we'd append in new headers such as X-User-Ip, etc.) | 541 // (roughly the amount we'd append in new headers such as X-User-Ip, etc.) |
571 BalsaHeaders(); | 542 BalsaHeaders(); |
572 ~BalsaHeaders(); | 543 ~BalsaHeaders(); |
573 | 544 |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 const HeaderLines::size_type end = header_lines_.size(); | 754 const HeaderLines::size_type end = header_lines_.size(); |
784 for (HeaderLines::size_type i = 0; i < end; ++i) { | 755 for (HeaderLines::size_type i = 0; i < end; ++i) { |
785 const HeaderLineDescription& line = header_lines_[i]; | 756 const HeaderLineDescription& line = header_lines_[i]; |
786 if (line.skip) { | 757 if (line.skip) { |
787 continue; | 758 continue; |
788 } | 759 } |
789 const char* line_ptr = GetPtr(line.buffer_base_idx); | 760 const char* line_ptr = GetPtr(line.buffer_base_idx); |
790 WriteHeaderLineToBuffer( | 761 WriteHeaderLineToBuffer( |
791 buffer, | 762 buffer, |
792 base::StringPiece(line_ptr + line.first_char_idx, | 763 base::StringPiece(line_ptr + line.first_char_idx, |
793 line.key_end_idx - line.first_char_idx), | 764 line.key_end_idx - line.first_char_idx), |
794 base::StringPiece(line_ptr + line.value_begin_idx, | 765 base::StringPiece(line_ptr + line.value_begin_idx, |
795 line.last_char_idx - line.value_begin_idx)); | 766 line.last_char_idx - line.value_begin_idx)); |
796 } | 767 } |
797 } | 768 } |
798 | 769 |
799 // Takes a header line in the form of a key/value pair and append it to the | 770 // Takes a header line in the form of a key/value pair and append it to the |
800 // buffer. This function should be called after WriteToBuffer to | 771 // buffer. This function should be called after WriteToBuffer to |
801 // append additional header lines to the header without copying the header. | 772 // append additional header lines to the header without copying the header. |
802 // When the user is done with appending to the buffer, | 773 // When the user is done with appending to the buffer, |
803 // WriteHeaderEndingToBuffer must be used to terminate the HTTP | 774 // WriteHeaderEndingToBuffer must be used to terminate the HTTP |
804 // header in the buffer. This method is a no-op if key is empty. | 775 // header in the buffer. This method is a no-op if key is empty. |
805 template <typename Buffer> | 776 template <typename Buffer> |
(...skipping 15 matching lines...) Expand all Loading... |
821 // This function can be called on a header object in any state. Raw header | 792 // This function can be called on a header object in any state. Raw header |
822 // data will be printed out if the header object is not completely parsed, | 793 // data will be printed out if the header object is not completely parsed, |
823 // e.g., when there was an error in the middle of parsing. | 794 // e.g., when there was an error in the middle of parsing. |
824 // The header content is appended to the string; the original content is not | 795 // The header content is appended to the string; the original content is not |
825 // cleared. | 796 // cleared. |
826 void DumpToString(std::string* str) const; | 797 void DumpToString(std::string* str) const; |
827 | 798 |
828 const base::StringPiece first_line() const { | 799 const base::StringPiece first_line() const { |
829 DCHECK_GE(whitespace_4_idx_, non_whitespace_1_idx_); | 800 DCHECK_GE(whitespace_4_idx_, non_whitespace_1_idx_); |
830 return base::StringPiece(BeginningOfFirstLine() + non_whitespace_1_idx_, | 801 return base::StringPiece(BeginningOfFirstLine() + non_whitespace_1_idx_, |
831 whitespace_4_idx_ - non_whitespace_1_idx_); | 802 whitespace_4_idx_ - non_whitespace_1_idx_); |
832 } | 803 } |
833 | 804 |
834 // Returns the parsed value of the response code if it has been parsed. | 805 // Returns the parsed value of the response code if it has been parsed. |
835 // Guaranteed to return 0 when unparsed (though it is a much better idea to | 806 // Guaranteed to return 0 when unparsed (though it is a much better idea to |
836 // verify that the BalsaFrame had no errors while parsing). | 807 // verify that the BalsaFrame had no errors while parsing). |
837 // This may return response codes which are outside the normal bounds of | 808 // This may return response codes which are outside the normal bounds of |
838 // HTTP response codes-- it is up to the user of this class to ensure that | 809 // HTTP response codes-- it is up to the user of this class to ensure that |
839 // the response code is one which is interpretable. | 810 // the response code is one which is interpretable. |
840 size_t parsed_response_code() const { return parsed_response_code_; } | 811 size_t parsed_response_code() const { return parsed_response_code_; } |
841 | 812 |
842 const base::StringPiece request_method() const { | 813 const base::StringPiece request_method() const { |
843 DCHECK_GE(whitespace_2_idx_, non_whitespace_1_idx_); | 814 DCHECK_GE(whitespace_2_idx_, non_whitespace_1_idx_); |
844 return base::StringPiece(BeginningOfFirstLine() + non_whitespace_1_idx_, | 815 return base::StringPiece(BeginningOfFirstLine() + non_whitespace_1_idx_, |
845 whitespace_2_idx_ - non_whitespace_1_idx_); | 816 whitespace_2_idx_ - non_whitespace_1_idx_); |
846 } | 817 } |
847 | 818 |
848 const base::StringPiece response_version() const { | 819 const base::StringPiece response_version() const { |
849 // Note: There is no difference between request_method() and | 820 // Note: There is no difference between request_method() and |
850 // response_version(). They both could be called | 821 // response_version(). They both could be called |
851 // GetFirstTokenFromFirstline()... but that wouldn't be anywhere near as | 822 // GetFirstTokenFromFirstline()... but that wouldn't be anywhere near as |
852 // descriptive. | 823 // descriptive. |
853 return request_method(); | 824 return request_method(); |
854 } | 825 } |
855 | 826 |
856 const base::StringPiece request_uri() const { | 827 const base::StringPiece request_uri() const { |
857 DCHECK_GE(whitespace_3_idx_, non_whitespace_2_idx_); | 828 DCHECK_GE(whitespace_3_idx_, non_whitespace_2_idx_); |
858 return base::StringPiece(BeginningOfFirstLine() + non_whitespace_2_idx_, | 829 return base::StringPiece(BeginningOfFirstLine() + non_whitespace_2_idx_, |
859 whitespace_3_idx_ - non_whitespace_2_idx_); | 830 whitespace_3_idx_ - non_whitespace_2_idx_); |
860 } | 831 } |
861 | 832 |
862 const base::StringPiece response_code() const { | 833 const base::StringPiece response_code() const { |
863 // Note: There is no difference between request_uri() and response_code(). | 834 // Note: There is no difference between request_uri() and response_code(). |
864 // They both could be called GetSecondtTokenFromFirstline(), but, as noted | 835 // They both could be called GetSecondtTokenFromFirstline(), but, as noted |
865 // in an earlier comment, that wouldn't be as descriptive. | 836 // in an earlier comment, that wouldn't be as descriptive. |
866 return request_uri(); | 837 return request_uri(); |
867 } | 838 } |
868 | 839 |
869 const base::StringPiece request_version() const { | 840 const base::StringPiece request_version() const { |
870 DCHECK_GE(whitespace_4_idx_, non_whitespace_3_idx_); | 841 DCHECK_GE(whitespace_4_idx_, non_whitespace_3_idx_); |
871 return base::StringPiece(BeginningOfFirstLine() + non_whitespace_3_idx_, | 842 return base::StringPiece(BeginningOfFirstLine() + non_whitespace_3_idx_, |
872 whitespace_4_idx_ - non_whitespace_3_idx_); | 843 whitespace_4_idx_ - non_whitespace_3_idx_); |
873 } | 844 } |
874 | 845 |
875 const base::StringPiece response_reason_phrase() const { | 846 const base::StringPiece response_reason_phrase() const { |
876 // Note: There is no difference between request_version() and | 847 // Note: There is no difference between request_version() and |
877 // response_reason_phrase(). They both could be called | 848 // response_reason_phrase(). They both could be called |
878 // GetThirdTokenFromFirstline(), but, as noted in an earlier comment, that | 849 // GetThirdTokenFromFirstline(), but, as noted in an earlier comment, that |
879 // wouldn't be as descriptive. | 850 // wouldn't be as descriptive. |
880 return request_version(); | 851 return request_version(); |
881 } | 852 } |
882 | 853 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 // Note: never check this for requests. Nothing bad will happen if you do, | 918 // Note: never check this for requests. Nothing bad will happen if you do, |
948 // but spec does not allow requests framed by connection close. | 919 // but spec does not allow requests framed by connection close. |
949 // TODO(vitaliyl): refactor. | 920 // TODO(vitaliyl): refactor. |
950 bool is_framed_by_connection_close() const { | 921 bool is_framed_by_connection_close() const { |
951 // We declare that response is framed by connection close if it has no | 922 // We declare that response is framed by connection close if it has no |
952 // content-length, no transfer encoding, and is allowed to have a body by | 923 // content-length, no transfer encoding, and is allowed to have a body by |
953 // the HTTP spec. | 924 // the HTTP spec. |
954 // parsed_response_code_ is 0 for requests, so ResponseCodeImpliesNoBody | 925 // parsed_response_code_ is 0 for requests, so ResponseCodeImpliesNoBody |
955 // will return false. | 926 // will return false. |
956 return (content_length_status_ == BalsaHeadersEnums::NO_CONTENT_LENGTH) && | 927 return (content_length_status_ == BalsaHeadersEnums::NO_CONTENT_LENGTH) && |
957 !transfer_encoding_is_chunked_ && | 928 !transfer_encoding_is_chunked_ && |
958 !ResponseCodeImpliesNoBody(parsed_response_code_); | 929 !ResponseCodeImpliesNoBody(parsed_response_code_); |
959 } | 930 } |
960 | 931 |
961 size_t content_length() const { return content_length_; } | 932 size_t content_length() const { return content_length_; } |
962 BalsaHeadersEnums::ContentLengthStatus content_length_status() const { | 933 BalsaHeadersEnums::ContentLengthStatus content_length_status() const { |
963 return content_length_status_; | 934 return content_length_status_; |
964 } | 935 } |
965 | 936 |
966 // SetContentLength and SetChunkEncoding modifies the header object to use | 937 // SetContentLength and SetChunkEncoding modifies the header object to use |
967 // content-length and transfer-encoding headers in a consistent manner. They | 938 // content-length and transfer-encoding headers in a consistent manner. They |
968 // set all internal flags and status so client can get a consistent view from | 939 // set all internal flags and status so client can get a consistent view from |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1038 bool append); | 1009 bool append); |
1039 | 1010 |
1040 HeaderLines::const_iterator GetConstHeaderLinesIterator( | 1011 HeaderLines::const_iterator GetConstHeaderLinesIterator( |
1041 const base::StringPiece& key, | 1012 const base::StringPiece& key, |
1042 HeaderLines::const_iterator start) const; | 1013 HeaderLines::const_iterator start) const; |
1043 | 1014 |
1044 HeaderLines::iterator GetHeaderLinesIteratorNoSkip( | 1015 HeaderLines::iterator GetHeaderLinesIteratorNoSkip( |
1045 const base::StringPiece& key, | 1016 const base::StringPiece& key, |
1046 HeaderLines::iterator start); | 1017 HeaderLines::iterator start); |
1047 | 1018 |
1048 HeaderLines::iterator GetHeaderLinesIterator( | 1019 HeaderLines::iterator GetHeaderLinesIterator(const base::StringPiece& key, |
1049 const base::StringPiece& key, | 1020 HeaderLines::iterator start); |
1050 HeaderLines::iterator start); | |
1051 | 1021 |
1052 template <typename IteratorType> | 1022 template <typename IteratorType> |
1053 const IteratorType HeaderLinesBeginHelper() const { | 1023 const IteratorType HeaderLinesBeginHelper() const { |
1054 if (header_lines_.empty()) { | 1024 if (header_lines_.empty()) { |
1055 return IteratorType(this, 0); | 1025 return IteratorType(this, 0); |
1056 } | 1026 } |
1057 const HeaderLines::size_type header_lines_size = header_lines_.size(); | 1027 const HeaderLines::size_type header_lines_size = header_lines_.size(); |
1058 for (HeaderLines::size_type i = 0; i < header_lines_size; ++i) { | 1028 for (HeaderLines::size_type i = 0; i < header_lines_size; ++i) { |
1059 if (header_lines_[i].skip == false) { | 1029 if (header_lines_[i].skip == false) { |
1060 return IteratorType(this, i); | 1030 return IteratorType(this, i); |
(...skipping 18 matching lines...) Expand all Loading... |
1079 return IteratorType(this, 0); | 1049 return IteratorType(this, 0); |
1080 } | 1050 } |
1081 | 1051 |
1082 // At the moment, this function will always return the original headers. | 1052 // At the moment, this function will always return the original headers. |
1083 // In the future, it may not do so after erasing header lines, modifying | 1053 // In the future, it may not do so after erasing header lines, modifying |
1084 // header lines, or modifying the first line. | 1054 // header lines, or modifying the first line. |
1085 // For this reason, it is strongly suggested that use of this function is | 1055 // For this reason, it is strongly suggested that use of this function is |
1086 // only acceptable for the purpose of debugging parse errors seen by the | 1056 // only acceptable for the purpose of debugging parse errors seen by the |
1087 // BalsaFrame class. | 1057 // BalsaFrame class. |
1088 base::StringPiece OriginalHeadersForDebugging() const { | 1058 base::StringPiece OriginalHeadersForDebugging() const { |
1089 return base::StringPiece(OriginalHeaderStreamBegin(), | 1059 return base::StringPiece( |
1090 OriginalHeaderStreamEnd() - OriginalHeaderStreamBegin()); | 1060 OriginalHeaderStreamBegin(), |
| 1061 OriginalHeaderStreamEnd() - OriginalHeaderStreamBegin()); |
1091 } | 1062 } |
1092 | 1063 |
1093 BalsaBuffer balsa_buffer_; | 1064 BalsaBuffer balsa_buffer_; |
1094 | 1065 |
1095 size_t content_length_; | 1066 size_t content_length_; |
1096 BalsaHeadersEnums::ContentLengthStatus content_length_status_; | 1067 BalsaHeadersEnums::ContentLengthStatus content_length_status_; |
1097 size_t parsed_response_code_; | 1068 size_t parsed_response_code_; |
1098 // HTTP firstlines all have the following structure: | 1069 // HTTP firstlines all have the following structure: |
1099 // LWS NONWS LWS NONWS LWS NONWS NOTCRLF CRLF | 1070 // LWS NONWS LWS NONWS LWS NONWS NOTCRLF CRLF |
1100 // [\t \r\n]+ [^\t ]+ [\t ]+ [^\t ]+ [\t ]+ [^\t ]+ [^\r\n]+ "\r\n" | 1071 // [\t \r\n]+ [^\t ]+ [\t ]+ [^\t ]+ [\t ]+ [^\t ]+ [^\r\n]+ "\r\n" |
(...skipping 28 matching lines...) Expand all Loading... |
1129 size_t end_of_firstline_idx_; | 1100 size_t end_of_firstline_idx_; |
1130 | 1101 |
1131 bool transfer_encoding_is_chunked_; | 1102 bool transfer_encoding_is_chunked_; |
1132 | 1103 |
1133 HeaderLines header_lines_; | 1104 HeaderLines header_lines_; |
1134 }; | 1105 }; |
1135 | 1106 |
1136 } // namespace net | 1107 } // namespace net |
1137 | 1108 |
1138 #endif // NET_TOOLS_BALSA_BALSA_HEADERS_H_ | 1109 #endif // NET_TOOLS_BALSA_BALSA_HEADERS_H_ |
OLD | NEW |