Line data Source code
1 : //
2 : // Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
3 : // Copyright (c) 2024 Christian Mazakas
4 : // Copyright (c) 2025 Mohammad Nejati
5 : //
6 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
7 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 : //
9 : // Official repository: https://github.com/cppalliance/http_proto
10 : //
11 :
12 : #ifndef BOOST_HTTP_PROTO_FIELDS_BASE_HPP
13 : #define BOOST_HTTP_PROTO_FIELDS_BASE_HPP
14 :
15 : #include <boost/http_proto/detail/config.hpp>
16 : #include <boost/http_proto/detail/except.hpp>
17 : #include <boost/http_proto/detail/header.hpp>
18 : #include <boost/core/detail/string_view.hpp>
19 :
20 : #include <iosfwd>
21 :
22 : namespace boost {
23 : namespace http_proto {
24 :
25 : /** Mixin for modifiable HTTP fields.
26 :
27 : @par Iterators
28 :
29 : Iterators obtained from @ref fields
30 : containers are not invalidated when
31 : the underlying container is modified.
32 :
33 : @note HTTP field names are case-insensitive.
34 : */
35 : class fields_base
36 : {
37 : detail::header h_;
38 : std::size_t max_cap_ =
39 : std::numeric_limits<std::size_t>::max();
40 : bool view_ = false;
41 :
42 : using entry =
43 : detail::header::entry;
44 : using offset_type =
45 : detail::header::offset_type;
46 : using table =
47 : detail::header::table;
48 :
49 : struct view_tag_t {};
50 : static constexpr view_tag_t view_tag{};
51 :
52 : class op_t;
53 : class prefix_op_t
54 : {
55 : fields_base& self_;
56 : offset_type new_prefix_;
57 : char* buf_ = nullptr;
58 :
59 : public:
60 : prefix_op_t(
61 : fields_base& self,
62 : std::size_t new_prefix,
63 : core::string_view* s0 = nullptr,
64 : core::string_view* s1 = nullptr);
65 :
66 : ~prefix_op_t();
67 : };
68 :
69 : friend class fields;
70 : friend class message_base;
71 : friend class request;
72 : friend class response;
73 : friend class parser;
74 : friend class request_parser;
75 : friend class response_parser;
76 : friend class serializer;
77 :
78 : BOOST_HTTP_PROTO_DECL
79 : explicit
80 : fields_base(
81 : detail::kind k) noexcept;
82 :
83 : BOOST_HTTP_PROTO_DECL
84 : fields_base(
85 : detail::kind k,
86 : core::string_view s);
87 :
88 : BOOST_HTTP_PROTO_DECL
89 : explicit
90 : fields_base(
91 : detail::header const& h);
92 :
93 : BOOST_HTTP_PROTO_DECL
94 : fields_base(
95 : fields_base const&);
96 :
97 : BOOST_HTTP_PROTO_DECL
98 : fields_base(
99 : view_tag_t,
100 : detail::header const& h);
101 :
102 : public:
103 : //--------------------------------------------
104 : //
105 : // Types
106 : //
107 : //--------------------------------------------
108 :
109 : /** A view to an HTTP field.
110 :
111 : The view will be invalidated when the
112 : underlying container is modified.
113 :
114 : The caller is responsible for ensuring
115 : that the lifetime of the container extends
116 : until it is no longer referenced.
117 : */
118 : struct reference
119 : {
120 : /** Field name constant.
121 :
122 : Set to `boost::none` if the constant
123 : does not exist in @ref field.
124 : */
125 : boost::optional<field> const id;
126 :
127 : /// A view to the field name.
128 : core::string_view const name;
129 :
130 : /// A view to the field value.
131 : core::string_view const value;
132 :
133 : reference const*
134 1731 : operator->() const noexcept
135 : {
136 1731 : return this;
137 : }
138 : };
139 :
140 : /// @copydoc reference
141 : typedef reference const_reference;
142 :
143 : /** A value type which represent an HTTP field.
144 :
145 : This type allows for making a copy of
146 : a field where ownership is retained
147 : in the copy.
148 : */
149 : struct value_type
150 : {
151 : /** Field name constant.
152 :
153 : Set to `boost::none` if the
154 : constant does not exist in @ref field.
155 : */
156 : boost::optional<field> id;
157 :
158 : /// Field name.
159 : std::string name;
160 :
161 : /// Field value.
162 : std::string value;
163 :
164 : /// Constructor.
165 : BOOST_HTTP_PROTO_DECL
166 : value_type(
167 : reference const& other);
168 :
169 : /** Conversion.
170 :
171 : @see
172 : @ref reference.
173 :
174 : @return A view to the fields.
175 : */
176 : operator reference() const noexcept;
177 : };
178 :
179 : /** A bidirectional iterator to HTTP fields.
180 : */
181 : class iterator;
182 :
183 : /// @copydoc iterator
184 : using const_iterator = iterator;
185 :
186 : /** A bidirectional reverse iterator to HTTP fields.
187 : */
188 : class reverse_iterator;
189 :
190 : /// @copydoc iterator
191 : using const_reverse_iterator = reverse_iterator;
192 :
193 : /** A forward range of matching fields.
194 :
195 : Objects of this type are returned by
196 : the function @ref find_all.
197 : */
198 : class subrange;
199 :
200 : //--------------------------------------------
201 : //
202 : // Special Members
203 : //
204 : //--------------------------------------------
205 :
206 : /** Destructor.
207 : */
208 : BOOST_HTTP_PROTO_DECL
209 : ~fields_base();
210 :
211 : //--------------------------------------------
212 : //
213 : // Observers
214 : //
215 : //--------------------------------------------
216 :
217 : /** Return the largest possible serialized message.
218 : */
219 : static
220 : constexpr
221 : std::size_t
222 : max_size() noexcept
223 : {
224 : // TODO: this doesn't take into account
225 : // the start-line
226 : return detail::header::max_offset;
227 : }
228 :
229 : /** Return an iterator to the beginning.
230 : */
231 : iterator
232 : begin() const noexcept;
233 :
234 : /** Return an iterator to the end.
235 : */
236 : iterator
237 : end() const noexcept;
238 :
239 : /** Return a reverse iterator to the beginning.
240 : */
241 : reverse_iterator
242 : rbegin() const noexcept;
243 :
244 : /** Return a reverse iterator to the end.
245 : */
246 : reverse_iterator
247 : rend() const noexcept;
248 :
249 : /** Return a string view representing the serialized data.
250 : */
251 : core::string_view
252 664 : buffer() const noexcept
253 : {
254 1328 : return core::string_view(
255 664 : h_.cbuf, h_.size);
256 : }
257 :
258 : /** Return the number of fields in the container.
259 : */
260 : std::size_t
261 184 : size() const noexcept
262 : {
263 184 : return h_.count;
264 : }
265 :
266 : /** Return the value of a field, or throws an exception.
267 :
268 : If more than one field with the specified
269 : name exists, the first field defined by
270 : insertion order is returned.
271 :
272 : @par Exception Safety
273 : Strong guarantee.
274 :
275 : @throw std::out_of_range
276 : Field is not found.
277 :
278 : @param id The field name constant.
279 : */
280 : BOOST_HTTP_PROTO_DECL
281 : core::string_view
282 : at(field id) const;
283 :
284 : /** Return the value of a field, or throws an exception.
285 :
286 : If more than one field with the specified
287 : name exists, the first field defined by
288 : insertion order is returned.
289 :
290 : If `name` refers to a known field, it is
291 : faster to call @ref at with a field id
292 : instead of a string.
293 :
294 : @par Exception Safety
295 : Strong guarantee.
296 :
297 : @throw std::out_of_range
298 : Field is not found.
299 :
300 : @param name The field name.
301 : */
302 : BOOST_HTTP_PROTO_DECL
303 : core::string_view
304 : at(core::string_view name) const;
305 :
306 : /** Return true if a field exists.
307 : */
308 : BOOST_HTTP_PROTO_DECL
309 : bool
310 : exists(field id) const noexcept;
311 :
312 : /** Return true if a field exists.
313 :
314 : If `name` refers to a known field,
315 : it is faster to call @ref exists
316 : with a field id instead of a string.
317 :
318 : @param name The field name.
319 : */
320 : BOOST_HTTP_PROTO_DECL
321 : bool
322 : exists(
323 : core::string_view name) const noexcept;
324 :
325 : /** Return the number of matching fields.
326 :
327 : @param id The field name constant.
328 : */
329 : BOOST_HTTP_PROTO_DECL
330 : std::size_t
331 : count(field id) const noexcept;
332 :
333 : /** Return the number of matching fields.
334 :
335 : If `name` refers to a known field,
336 : it is faster to call @ref count
337 : with a field id instead of a string.
338 :
339 : @param name The field name.
340 : */
341 : BOOST_HTTP_PROTO_DECL
342 : std::size_t
343 : count(
344 : core::string_view name) const noexcept;
345 :
346 : /** Return an iterator to the matching element if it exists.
347 :
348 : @param id The field name constant.
349 : */
350 : BOOST_HTTP_PROTO_DECL
351 : iterator
352 : find(field id) const noexcept;
353 :
354 : /** Return an iterator to the matching element if it exists.
355 :
356 : If `name` refers to a known field,
357 : it is faster to call @ref find
358 : with a field id instead of a string.
359 :
360 : @param name The field name.
361 : */
362 : BOOST_HTTP_PROTO_DECL
363 : iterator
364 : find(
365 : core::string_view name) const noexcept;
366 :
367 : /** Return an iterator to the matching element if it exists.
368 :
369 : @param from The position to begin the
370 : search from. This can be `end()`.
371 :
372 : @param id The field name constant.
373 : */
374 : BOOST_HTTP_PROTO_DECL
375 : iterator
376 : find(
377 : iterator from,
378 : field id) const noexcept;
379 :
380 : /** Return an iterator to the matching element if it exists.
381 :
382 : If `name` refers to a known field,
383 : it is faster to call @ref find
384 : with a field id instead of a string.
385 :
386 : @param from The position to begin the
387 : search from. This can be `end()`.
388 :
389 : @param name The field name.
390 : */
391 : BOOST_HTTP_PROTO_DECL
392 : iterator
393 : find(
394 : iterator from,
395 : core::string_view name) const noexcept;
396 :
397 : /** Return an iterator to the matching element if it exists.
398 :
399 : @param before One past the position
400 : to begin the search from. This can
401 : be `end()`.
402 :
403 : @param id The field name constant.
404 : */
405 : BOOST_HTTP_PROTO_DECL
406 : iterator
407 : find_last(
408 : iterator before,
409 : field id) const noexcept;
410 :
411 : /** Return an iterator to the matching element if it exists.
412 :
413 : If `name` refers to a known field,
414 : it is faster to call @ref find_last
415 : with a field id instead of a string.
416 :
417 : @param before One past the position
418 : to begin the search from. This can
419 : be `end()`.
420 :
421 : @param name The field name.
422 : */
423 : BOOST_HTTP_PROTO_DECL
424 : iterator
425 : find_last(
426 : iterator before,
427 : core::string_view name) const noexcept;
428 :
429 : /** Return the value of a field or a default if missing.
430 :
431 : @param id The field name constant.
432 :
433 : @param s The value to be returned if
434 : field does not exist.
435 : */
436 : BOOST_HTTP_PROTO_DECL
437 : core::string_view
438 : value_or(
439 : field id,
440 : core::string_view s) const noexcept;
441 :
442 : /** Return the value of a field or a default if missing.
443 :
444 : If `name` refers to a known field,
445 : it is faster to call @ref value_or
446 : with a field id instead of a string.
447 :
448 : @param name The field name.
449 :
450 : @param s The value to be returned if
451 : field does not exist.
452 : */
453 : BOOST_HTTP_PROTO_DECL
454 : core::string_view
455 : value_or(
456 : core::string_view name,
457 : core::string_view s) const noexcept;
458 :
459 : /** Return a forward range containing values for all matching fields.
460 :
461 : @param id The field name constant.
462 : */
463 : BOOST_HTTP_PROTO_DECL
464 : subrange
465 : find_all(field id) const noexcept;
466 :
467 : /** Return a forward range containing values for all matching fields.
468 :
469 : If `name` refers to a known field,
470 : it is faster to call @ref find_all
471 : with a field id instead of a string.
472 :
473 : @param name The field name.
474 : */
475 : BOOST_HTTP_PROTO_DECL
476 : subrange
477 : find_all(
478 : core::string_view name) const noexcept;
479 :
480 : //--------------------------------------------
481 : //
482 : // Capacity
483 : //
484 : //--------------------------------------------
485 :
486 : /** Return the maximum allowed capacity in bytes.
487 : */
488 : std::size_t
489 22 : max_capacity_in_bytes() noexcept
490 : {
491 22 : return max_cap_;
492 : }
493 :
494 : /** Return the total number of bytes allocated by the container.
495 : */
496 : std::size_t
497 97 : capacity_in_bytes() const noexcept
498 : {
499 97 : return h_.cap;
500 : }
501 :
502 : /** Clear contents while preserving the capacity.
503 :
504 : In the case of response and request
505 : containers the start-line also resets to
506 : default.
507 :
508 : @par Postconditions
509 : @code
510 : this->size() == 0
511 : @endcode
512 :
513 : @par Complexity
514 : Constant.
515 : */
516 : BOOST_HTTP_PROTO_DECL
517 : void
518 : clear() noexcept;
519 :
520 : /** Adjust the capacity without changing the size.
521 :
522 : This function adjusts the capacity
523 : of the container in bytes, without
524 : affecting the current contents. Has
525 : no effect if `n <= this->capacity_in_bytes()`.
526 :
527 : @par Postconditions
528 : @code
529 : this->capacity_in_bytes() >= n
530 : @endcode
531 :
532 : @par Exception Safety
533 : Strong guarantee.
534 : Calls to allocate may throw.
535 : Exception thrown if max capacity exceeded.
536 :
537 : @throw std::length_error
538 : Max capacity would be exceeded.
539 :
540 : @param n The capacity in bytes.
541 : */
542 : BOOST_HTTP_PROTO_DECL
543 : void
544 : reserve_bytes(std::size_t n);
545 :
546 : /** Set the maximum allowed capacity in bytes.
547 :
548 : Prevents the container from growing beyond
549 : `n` bytes. Exceeding this limit will throw
550 : an exception.
551 :
552 : @par Preconditions
553 : @code
554 : this->capacity_in_bytes() <= n
555 : @endcode
556 :
557 : @par Postconditions
558 : @code
559 : this->max_capacity_in_bytes() == n
560 : @endcode
561 :
562 : @par Exception Safety
563 : Strong guarantee.
564 : Exception thrown on invalid input.
565 :
566 : @throw std::invalid_argument
567 : `n < this->capacity_in_bytes()`
568 :
569 : @param n The maximum allowed capacity in bytes.
570 : */
571 : BOOST_HTTP_PROTO_DECL
572 : void
573 : set_max_capacity_in_bytes(std::size_t n);
574 :
575 : /** Remove excess capacity.
576 :
577 : @par Exception Safety
578 : Strong guarantee.
579 : Calls to allocate may throw.
580 : */
581 : BOOST_HTTP_PROTO_DECL
582 : void
583 : shrink_to_fit();
584 :
585 : //--------------------------------------------
586 : //
587 : // Modifiers
588 : //
589 : //--------------------------------------------
590 :
591 : /** Append a header.
592 :
593 : This function appends a new header.
594 : Existing headers with the same name are
595 : not changed.
596 :
597 : Any leading or trailing whitespace in the
598 : value is ignored.
599 :
600 : No iterators are invalidated.
601 :
602 : @par Example
603 : @code
604 : request req;
605 :
606 : req.append( field::user_agent, "Boost" );
607 : @endcode
608 :
609 : @par Complexity
610 : Linear in `to_string( id ).size() + value.size()`.
611 :
612 : @par Exception Safety
613 : Strong guarantee.
614 : Calls to allocate may throw.
615 : Exception thrown on invalid input.
616 : Exception thrown if max capacity exceeded.
617 :
618 : @throw system_error
619 : Input is invalid.
620 :
621 : @throw std::length_error
622 : Max capacity would be exceeded.
623 :
624 : @param id The field name constant.
625 :
626 : @param value The value which must be semantically
627 : valid for the message.
628 : */
629 : void
630 92 : append(
631 : field id,
632 : core::string_view value)
633 : {
634 92 : system::error_code ec;
635 92 : append(id, value, ec);
636 89 : if(ec.failed())
637 3 : detail::throw_system_error(ec);
638 86 : }
639 :
640 : /** Append a header.
641 :
642 : This function appends a new header.
643 : Existing headers with the same name are
644 : not changed.
645 :
646 : Any leading or trailing whitespace in the
647 : value is ignored.
648 :
649 : No iterators are invalidated.
650 :
651 : @par Example
652 : @code
653 : request req;
654 :
655 : req.append( field::user_agent, "Boost" );
656 : @endcode
657 :
658 : @par Complexity
659 : Linear in `to_string( id ).size() + value.size()`.
660 :
661 : @par Exception Safety
662 : Strong guarantee.
663 : Calls to allocate may throw.
664 : Exception thrown if max capacity exceeded.
665 :
666 : @throw std::length_error
667 : Max capacity would be exceeded.
668 :
669 : @param id The field name constant.
670 :
671 : @param value The value which must be semantically
672 : valid for the message.
673 :
674 : @param ec Set to the error if input is invalid.
675 : */
676 : void
677 92 : append(
678 : field id,
679 : core::string_view value,
680 : system::error_code& ec)
681 : {
682 92 : insert_impl(
683 : id,
684 : to_string(id),
685 : value,
686 92 : h_.count,
687 : ec);
688 89 : }
689 :
690 : /** Append a header.
691 :
692 : This function appends a new header.
693 : Existing headers with the same name are
694 : not changed.
695 :
696 : Any leading or trailing whitespace in the
697 : value is ignored.
698 :
699 : No iterators are invalidated.
700 :
701 : @par Example
702 : @code
703 : request req;
704 :
705 : req.append( "User-Agent", "Boost" );
706 : @endcode
707 :
708 : @par Complexity
709 : Linear in `name.size() + value.size()`.
710 :
711 : @par Exception Safety
712 : Strong guarantee.
713 : Calls to allocate may throw.
714 : Exception thrown on invalid input.
715 : Exception thrown if max capacity exceeded.
716 :
717 : @throw system_error
718 : Input is invalid.
719 :
720 : @throw std::length_error
721 : Max capacity would be exceeded.
722 :
723 : @param name The header name.
724 :
725 : @param value The header value, which must
726 : be semantically valid for the message.
727 : */
728 : void
729 44 : append(
730 : core::string_view name,
731 : core::string_view value)
732 : {
733 44 : system::error_code ec;
734 44 : append(name, value, ec);
735 43 : if(ec.failed())
736 1 : detail::throw_system_error(ec);
737 42 : }
738 :
739 : /** Append a header.
740 :
741 : This function appends a new header.
742 : Existing headers with the same name are
743 : not changed.
744 :
745 : Any leading or trailing whitespace in the
746 : value is ignored.
747 :
748 : No iterators are invalidated.
749 :
750 : @par Example
751 : @code
752 : request req;
753 :
754 : req.append( "User-Agent", "Boost" );
755 : @endcode
756 :
757 : @par Complexity
758 : Linear in `name.size() + value.size()`.
759 :
760 : @par Exception Safety
761 : Strong guarantee.
762 : Calls to allocate may throw.
763 : Exception thrown if max capacity exceeded.
764 :
765 : @throw std::length_error
766 : Max capacity would be exceeded.
767 :
768 : @param name The header name.
769 :
770 : @param value The value which must be semantically
771 : valid for the message.
772 :
773 : @param ec Set to the error if input is invalid.
774 : */
775 : void
776 57 : append(
777 : core::string_view name,
778 : core::string_view value,
779 : system::error_code& ec)
780 : {
781 57 : insert_impl(
782 : string_to_field(name),
783 : name,
784 : value,
785 57 : h_.count,
786 : ec);
787 56 : }
788 :
789 : /** Insert a header.
790 :
791 : If a matching header with the same name
792 : exists, it is not replaced. Instead, an
793 : additional header with the same name is
794 : inserted. Names are not case-sensitive.
795 : Any leading or trailing whitespace in
796 : the new value is ignored.
797 :
798 : All iterators that are equal to `before`
799 : or come after are invalidated.
800 :
801 : @par Example
802 : @code
803 : request req;
804 :
805 : req.insert( req.begin(), field::user_agent, "Boost" );
806 : @endcode
807 :
808 : @par Complexity
809 : Linear in `to_string( id ).size() + value.size()`.
810 :
811 : @par Exception Safety
812 : Strong guarantee.
813 : Calls to allocate may throw.
814 : Exception thrown on invalid input.
815 : Exception thrown if max capacity exceeded.
816 :
817 : @throw system_error
818 : Input is invalid.
819 :
820 : @throw std::length_error
821 : Max capacity would be exceeded.
822 :
823 : @return An iterator to the newly inserted header.
824 :
825 : @param before Position to insert before.
826 :
827 : @param id The field name constant.
828 :
829 : @param value The value which must be semantically
830 : valid for the message.
831 : */
832 : BOOST_HTTP_PROTO_DECL
833 : iterator
834 : insert(
835 : iterator before,
836 : field id,
837 : core::string_view value);
838 :
839 : /** Insert a header.
840 :
841 : If a matching header with the same name
842 : exists, it is not replaced. Instead, an
843 : additional header with the same name is
844 : inserted. Names are not case-sensitive.
845 :
846 : Any leading or trailing whitespace in
847 : the new value is ignored.
848 :
849 : All iterators that are equal to `before`
850 : or come after are invalidated.
851 :
852 : @par Example
853 : @code
854 : request req;
855 :
856 : req.insert( req.begin(), field::user_agent, "Boost" );
857 : @endcode
858 :
859 : @par Complexity
860 : Linear in `to_string( id ).size() + value.size()`.
861 :
862 : @par Exception Safety
863 : Strong guarantee.
864 : Calls to allocate may throw.
865 : Exception thrown if max capacity exceeded.
866 :
867 : @throw std::length_error
868 : Max capacity would be exceeded.
869 :
870 : @return An iterator to the newly inserted header.
871 :
872 : @param before Position to insert before.
873 :
874 : @param id The field name constant.
875 :
876 : @param value The value which must be semantically
877 : valid for the message.
878 :
879 : @param ec Set to the error if input is invalid.
880 : */
881 : BOOST_HTTP_PROTO_DECL
882 : iterator
883 : insert(
884 : iterator before,
885 : field id,
886 : core::string_view value,
887 : system::error_code& ec);
888 :
889 : /** Insert a header.
890 :
891 : If a matching header with the same name
892 : exists, it is not replaced. Instead, an
893 : additional header with the same name is
894 : inserted. Names are not case-sensitive.
895 :
896 : Any leading or trailing whitespace in
897 : the new value is ignored.
898 :
899 : All iterators that are equal to `before`
900 : or come after are invalidated.
901 :
902 : @par Example
903 : @code
904 : request req;
905 :
906 : req.insert( req.begin(), "User-Agent", "Boost" );
907 : @endcode
908 :
909 : @par Complexity
910 : Linear in `name.size() + value.size()`.
911 :
912 : @par Exception Safety
913 : Strong guarantee.
914 : Calls to allocate may throw.
915 : Exception thrown on invalid input.
916 : Exception thrown if max capacity exceeded.
917 :
918 : @throw system_error
919 : Input is invalid.
920 :
921 : @throw std::length_error
922 : Max capacity would be exceeded.
923 :
924 : @return An iterator to the newly inserted header.
925 :
926 : @param before Position to insert before.
927 :
928 : @param name The header name.
929 :
930 : @param value The value which must be semantically
931 : valid for the message.
932 : */
933 : BOOST_HTTP_PROTO_DECL
934 : iterator
935 : insert(
936 : iterator before,
937 : core::string_view name,
938 : core::string_view value);
939 :
940 : /** Insert a header.
941 :
942 : If a matching header with the same name
943 : exists, it is not replaced. Instead, an
944 : additional header with the same name is
945 : inserted. Names are not case-sensitive.
946 :
947 : Any leading or trailing whitespace in
948 : the new value is ignored.
949 :
950 : All iterators that are equal to `before`
951 : or come after are invalidated.
952 :
953 : @par Example
954 : @code
955 : request req;
956 :
957 : req.insert( req.begin(), "User-Agent", "Boost" );
958 : @endcode
959 :
960 : @par Complexity
961 : Linear in `name.size() + value.size()`.
962 :
963 : @par Exception Safety
964 : Strong guarantee.
965 : Calls to allocate may throw.
966 : Exception thrown if max capacity exceeded.
967 :
968 : @throw std::length_error
969 : Max capacity would be exceeded.
970 :
971 : @return An iterator to the newly inserted header.
972 :
973 : @param before Position to insert before.
974 :
975 : @param name The header name.
976 :
977 : @param value The value which must be semantically
978 : valid for the message.
979 :
980 : @param ec Set to the error if input is invalid.
981 : */
982 : BOOST_HTTP_PROTO_DECL
983 : iterator
984 : insert(
985 : iterator before,
986 : core::string_view name,
987 : core::string_view value,
988 : system::error_code& ec);
989 :
990 : //--------------------------------------------
991 :
992 : /** Erase headers.
993 :
994 : This function removes the header pointed
995 : to by `it`.
996 :
997 : All iterators that are equal to `it`
998 : or come after are invalidated.
999 :
1000 : @par Complexity
1001 : Linear in `name.size() + value.size()`.
1002 :
1003 : @return An iterator to one past the
1004 : removed element.
1005 :
1006 : @param it The iterator to the element
1007 : to erase.
1008 : */
1009 : BOOST_HTTP_PROTO_DECL
1010 : iterator
1011 : erase(iterator it) noexcept;
1012 :
1013 : /** Erase headers.
1014 :
1015 : This removes all headers whose name
1016 : constant is equal to `id`.
1017 :
1018 : If any headers are erased, then all
1019 : iterators equal to or that come after
1020 : the first erased element are invalidated.
1021 : Otherwise, no iterators are invalidated.
1022 :
1023 : @par Complexity
1024 : Linear in `this->string().size()`.
1025 :
1026 : @return The number of headers erased.
1027 :
1028 : @param id The field name constant.
1029 : */
1030 : BOOST_HTTP_PROTO_DECL
1031 : std::size_t
1032 : erase(field id) noexcept;
1033 :
1034 : /** Erase all matching fields.
1035 :
1036 : This removes all headers with a matching
1037 : name, using a case-insensitive comparison.
1038 :
1039 : If any headers are erased, then all
1040 : iterators equal to or that come after
1041 : the first erased element are invalidated.
1042 : Otherwise, no iterators are invalidated.
1043 :
1044 : @par Complexity
1045 : Linear in `this->string().size()`.
1046 :
1047 : @return The number of fields erased
1048 :
1049 : @param name The header name.
1050 : */
1051 : BOOST_HTTP_PROTO_DECL
1052 : std::size_t
1053 : erase(
1054 : core::string_view name) noexcept;
1055 :
1056 : //--------------------------------------------
1057 :
1058 : /** Set a header value.
1059 :
1060 : Uses the given value to overwrite the
1061 : current one in the header field pointed to
1062 : by the iterator. The value must be
1063 : syntactically valid or else an error is
1064 : returned.
1065 :
1066 : Any leading or trailing whitespace in the
1067 : new value is ignored.
1068 :
1069 : @par Complexity
1070 :
1071 : @par Exception Safety
1072 : Strong guarantee.
1073 : Calls to allocate may throw.
1074 : Exception thrown on invalid input.
1075 : Exception thrown if max capacity exceeded.
1076 :
1077 : @throw system_error
1078 : Input is invalid.
1079 :
1080 : @throw std::length_error
1081 : Max capacity would be exceeded.
1082 :
1083 : @param it The iterator to the header.
1084 :
1085 : @param value The value which must be semantically
1086 : valid for the message.
1087 : */
1088 : BOOST_HTTP_PROTO_DECL
1089 : void
1090 : set(iterator it, core::string_view value);
1091 :
1092 : /** Set a header value.
1093 :
1094 : Uses the given value to overwrite the
1095 : current one in the header field pointed to
1096 : by the iterator. The value must be
1097 : syntactically valid or else an error is
1098 : returned.
1099 :
1100 : Any leading or trailing whitespace in the
1101 : new value is ignored.
1102 :
1103 : @par Complexity
1104 :
1105 : @par Exception Safety
1106 : Strong guarantee.
1107 : Calls to allocate may throw.
1108 : Exception thrown if max capacity exceeded.
1109 :
1110 : @throw std::length_error
1111 : Max capacity would be exceeded.
1112 :
1113 : @param it The iterator to the header.
1114 :
1115 : @param value The value which must be semantically
1116 : valid for the message.
1117 :
1118 : @param ec Set to the error if input is invalid.
1119 : */
1120 : BOOST_HTTP_PROTO_DECL
1121 : void
1122 : set(
1123 : iterator it,
1124 : core::string_view value,
1125 : system::error_code& ec);
1126 :
1127 : /** Set a header value.
1128 :
1129 : The container is modified to contain
1130 : exactly one field with the specified id
1131 : set to the given value, which must be
1132 : syntactically valid or else an error is
1133 : returned.
1134 :
1135 : Any leading or trailing whitespace in the
1136 : new value is ignored.
1137 :
1138 : @par Postconditions
1139 : @code
1140 : this->count( id ) == 1 && this->at( id ) == value
1141 : @endcode
1142 :
1143 : @par Complexity
1144 :
1145 : @par Exception Safety
1146 : Strong guarantee.
1147 : Calls to allocate may throw.
1148 : Exception thrown on invalid input.
1149 : Exception thrown if max capacity exceeded.
1150 :
1151 : @throw system_error
1152 : Input is invalid.
1153 :
1154 : @throw std::length_error
1155 : Max capacity would be exceeded.
1156 :
1157 : @param id The field constant of the header
1158 : to set.
1159 :
1160 : @param value The value which must be semantically
1161 : valid for the message.
1162 : */
1163 : void
1164 106 : set(
1165 : field id,
1166 : core::string_view value)
1167 : {
1168 106 : system::error_code ec;
1169 106 : set(id, value, ec);
1170 106 : if(ec.failed())
1171 2 : detail::throw_system_error(ec);
1172 104 : }
1173 :
1174 : /** Set a header value.
1175 :
1176 : The container is modified to contain
1177 : exactly one field with the specified id
1178 : set to the given value, which must be
1179 : syntactically valid or else an error is
1180 : returned.
1181 :
1182 : Any leading or trailing whitespace in the
1183 : new value is ignored.
1184 :
1185 : @par Postconditions
1186 : @code
1187 : this->count( id ) == 1 && this->at( id ) == value
1188 : @endcode
1189 :
1190 : @par Complexity
1191 :
1192 : @par Exception Safety
1193 : Strong guarantee.
1194 : Calls to allocate may throw.
1195 : Exception thrown if max capacity exceeded.
1196 :
1197 : @throw std::length_error
1198 : Max capacity would be exceeded.
1199 :
1200 : @param id The field name constant.
1201 :
1202 : @param value The value which must be semantically
1203 : valid for the message.
1204 :
1205 : @param ec Set to the error if input is invalid.
1206 : */
1207 : BOOST_HTTP_PROTO_DECL
1208 : void
1209 : set(
1210 : field id,
1211 : core::string_view value,
1212 : system::error_code& ec);
1213 :
1214 : /** Set a header value.
1215 :
1216 : The container is modified to contain
1217 : exactly one field with the specified name
1218 : set to the given value, which must be
1219 : syntactically valid or else an error is
1220 : returned.
1221 :
1222 : Any leading or trailing whitespace in the
1223 : new value is ignored.
1224 :
1225 : @par Postconditions
1226 : @code
1227 : this->count( name ) == 1 && this->at( name ) == value
1228 : @endcode
1229 :
1230 : @par Complexity
1231 :
1232 : @par Exception Safety
1233 : Strong guarantee.
1234 : Calls to allocate may throw.
1235 : Exception thrown on invalid input.
1236 : Exception thrown if max capacity exceeded.
1237 :
1238 : @throw system_error
1239 : Input is invalid.
1240 :
1241 : @throw std::length_error
1242 : Max capacity would be exceeded.
1243 :
1244 : @param name The field name.
1245 :
1246 : @param value The value which must be semantically
1247 : valid for the message.
1248 : */
1249 : void
1250 28 : set(
1251 : core::string_view name,
1252 : core::string_view value)
1253 : {
1254 28 : system::error_code ec;
1255 28 : set(name, value, ec);
1256 27 : if(ec.failed())
1257 4 : detail::throw_system_error(ec);
1258 23 : }
1259 :
1260 : /** Set a header value.
1261 :
1262 : The container is modified to contain
1263 : exactly one field with the specified name
1264 : set to the given value, which must be
1265 : syntactically valid or else an error is
1266 : returned.
1267 :
1268 : Any leading or trailing whitespace in the
1269 : new value is ignored.
1270 :
1271 : @par Postconditions
1272 : @code
1273 : this->count( name ) == 1 && this->at( name ) == value
1274 : @endcode
1275 :
1276 : @par Complexity
1277 :
1278 : @par Exception Safety
1279 : Strong guarantee.
1280 : Calls to allocate may throw.
1281 : Exception thrown if max capacity exceeded.
1282 :
1283 : @throw std::length_error
1284 : Max capacity would be exceeded.
1285 :
1286 : @param name The field name.
1287 :
1288 : @param value The value which must be semantically
1289 : valid for the message.
1290 :
1291 : @param ec Set to the error if input is invalid.
1292 : */
1293 : BOOST_HTTP_PROTO_DECL
1294 : void
1295 : set(
1296 : core::string_view name,
1297 : core::string_view value,
1298 : system::error_code& ec);
1299 :
1300 : //--------------------------------------------
1301 :
1302 : /** Format the container to the output stream
1303 :
1304 : This function serializes the container to
1305 : the specified output stream.
1306 :
1307 : @par Example
1308 : @code
1309 : request req;
1310 : req.set(field::content_length, "42");
1311 : std::stringstream ss;
1312 : ss << req;
1313 : assert( ss.str() == "GET / HTTP/1.1\nContent-Length: 42\n" );
1314 : @endcode
1315 :
1316 : @par Effects
1317 : @code
1318 : return os << f.buffer();
1319 : @endcode
1320 :
1321 : @par Complexity
1322 : Linear in `f.buffer().size()`
1323 :
1324 : @par Exception Safety
1325 : Basic guarantee.
1326 :
1327 : @return A reference to the output stream, for chaining
1328 :
1329 : @param os The output stream to write to.
1330 :
1331 : @param f The container to write.
1332 : */
1333 : friend
1334 : BOOST_HTTP_PROTO_DECL
1335 : std::ostream&
1336 : operator<<(
1337 : std::ostream& os,
1338 : const fields_base& f);
1339 :
1340 : private:
1341 : BOOST_HTTP_PROTO_DECL
1342 : void
1343 : copy_impl(
1344 : detail::header const&);
1345 :
1346 : void
1347 : clone_if_needed();
1348 :
1349 : BOOST_HTTP_PROTO_DECL
1350 : void
1351 : insert_impl(
1352 : optional<field> id,
1353 : core::string_view name,
1354 : core::string_view value,
1355 : std::size_t before,
1356 : system::error_code& ec);
1357 :
1358 : void
1359 : insert_unchecked(
1360 : optional<field> id,
1361 : core::string_view name,
1362 : core::string_view value,
1363 : std::size_t before,
1364 : bool has_obs_fold);
1365 :
1366 : void
1367 : raw_erase(
1368 : std::size_t) noexcept;
1369 :
1370 : void
1371 : raw_erase_n(field, std::size_t) noexcept;
1372 :
1373 : std::size_t
1374 : erase_all(
1375 : std::size_t i0,
1376 : field id) noexcept;
1377 :
1378 : std::size_t
1379 : erase_all(
1380 : std::size_t i0,
1381 : core::string_view name) noexcept;
1382 :
1383 : std::size_t
1384 : offset(
1385 : std::size_t i) const noexcept;
1386 :
1387 : std::size_t
1388 : length(
1389 : std::size_t i) const noexcept;
1390 : };
1391 :
1392 : } // http_proto
1393 : } // boost
1394 :
1395 : #include <boost/http_proto/impl/fields_base.hpp>
1396 :
1397 : #endif
|