RESTinio

message_builders.hpp
Go to the documentation of this file.
1/*
2 restinio
3*/
4
9#pragma once
10
11#include <ctime>
12#include <chrono>
13
14#include <restinio/impl/include_fmtlib.hpp>
15
16#include <restinio/common_types.hpp>
17#include <restinio/http_headers.hpp>
18#include <restinio/os.hpp>
19#include <restinio/sendfile.hpp>
20#include <restinio/impl/connection_base.hpp>
21
22#include <restinio/impl/header_helpers.hpp>
23
24 namespace restinio
25{
26
27//
28// make_date_field_value()
29//
30
32 inline std::string
33 make_date_field_value( std::time_t t )
34{
35 const auto tpoint = make_gmtime( t );
36
37 std::array< char, 64 > buf;
38 // TODO: is there a faster way to get time string?
39 strftime(
40 buf.data(),
41 buf.size(),
42 "%a, %d %b %Y %H:%M:%S GMT",
43 &tpoint );
44
45 return std::string{ buf.data() };
46}
47
48 inline std::string
49 make_date_field_value( std::chrono::system_clock::time_point tp )
50{
51 return make_date_field_value( std::chrono::system_clock::to_time_t( tp ) );
52}
53
54//
55// base_response_builder_t
56//
57
58 template < typename Response_Builder >
59 class base_response_builder_t
60{
61 public:
62 base_response_builder_t( const base_response_builder_t & ) = delete;
63 base_response_builder_t & operator = ( const base_response_builder_t & ) = delete;
64
65 base_response_builder_t( base_response_builder_t && ) noexcept = default;
66 base_response_builder_t & operator =( base_response_builder_t && ) noexcept = default;
67
68 virtual ~base_response_builder_t() = default;
69
70 base_response_builder_t(
71 http_status_line_t status_line,
72 impl::connection_handle_t connection,
73 request_id_t request_id,
74 bool should_keep_alive )
75 : m_header{ std::move( status_line ) }
76 , m_connection{ std::move( connection ) }
77 , m_request_id{ request_id }
78 {
79 m_header.should_keep_alive( should_keep_alive );
80 }
81
84 http_response_header_t &
85 header() noexcept
86 {
87 return m_header;
88 }
89
90 const http_response_header_t &
91 header() const noexcept
92 {
93 return m_header;
94 }
96
98 Response_Builder &
99 append_header(
100 std::string field_name,
101 std::string field_value ) &
102 {
103 m_header.add_field(
104 std::move( field_name ),
105 std::move( field_value ) );
106 return upcast_reference();
107 }
108
110 Response_Builder &&
111 append_header(
112 std::string field_name,
113 std::string field_value ) &&
114 {
115 return std::move( this->append_header(
116 std::move( field_name ),
117 std::move( field_value ) ) );
118 }
119
121 Response_Builder &
122 append_header( http_header_field_t http_header_field ) &
123 {
124 m_header.add_field( std::move( http_header_field ) );
125 return upcast_reference();
126 }
127
129 Response_Builder &&
130 append_header( http_header_field_t http_header_field ) &&
131 {
132 return std::move( this->append_header(
133 std::move( http_header_field ) ) );
134 }
135
137 Response_Builder &
138 append_header(
139 http_field_t field_id,
140 std::string field_value ) &
141 {
142 m_header.add_field(
143 field_id,
144 std::move( field_value ) );
145 return upcast_reference();
146 }
147
149 Response_Builder &&
150 append_header(
151 http_field_t field_id,
152 std::string field_value ) &&
153 {
154 return std::move( this->append_header(
155 field_id,
156 std::move( field_value ) ) );
157 }
158
159
161 Response_Builder &
162 append_header_date_field(
163 std::chrono::system_clock::time_point tp =
164 std::chrono::system_clock::now() ) &
165 {
166 m_header.set_field( http_field_t::date, make_date_field_value( tp ) );
167 return upcast_reference();
168 }
169
171 Response_Builder &&
172 append_header_date_field(
173 std::chrono::system_clock::time_point tp =
174 std::chrono::system_clock::now() ) &&
175 {
176 return std::move( this->append_header_date_field( tp ) );
177 }
178
180 Response_Builder &
181 connection_close() & noexcept
182 {
183 m_header.should_keep_alive( false );
184 return upcast_reference();
185 }
186
188 Response_Builder &&
189 connection_close() && noexcept
190 {
191 return std::move( this->connection_close() );
192 }
193
194
196 Response_Builder &
197 connection_keep_alive() & noexcept
198 {
199 m_header.should_keep_alive();
200 return upcast_reference();
201 }
202
203 Response_Builder &&
204 connection_keep_alive() && noexcept
205 {
206 return std::move( this->connection_keep_alive() );
207 }
208
209 protected:
210 std::size_t
211 calculate_status_line_size() const noexcept
212 {
213 // "HTTP/1.1 *** <reason-phrase>"
214 return 8 + 1 + 3 + 1 + m_header.status_line().reason_phrase().size();
215 }
216
217 http_response_header_t m_header;
218
219 impl::connection_handle_t m_connection;
220 const request_id_t m_request_id;
221
222 void
223 throw_done_must_be_called_once() const
224 {
225 throw exception_t{ "done() cannot be called twice" };
226 }
227
228 private:
229 Response_Builder &
230 upcast_reference() noexcept
231 {
232 return static_cast< Response_Builder & >( *this );
233 }
234};
235
236//
237// response_builder_t
238//
239
241 template < typename Response_Output_Strategy >
242 class response_builder_t
243{
244 response_builder_t() = delete;
245};
246
248 struct restinio_controlled_output_t {};
249
251
257 template <>
258 class response_builder_t< restinio_controlled_output_t > final
259 : public base_response_builder_t< response_builder_t< restinio_controlled_output_t > >
260{
261 public:
262 using base_type_t =
263 base_response_builder_t< response_builder_t< restinio_controlled_output_t > >;
264 using self_type_t =
265 response_builder_t< restinio_controlled_output_t >;
266
267 response_builder_t( response_builder_t && ) = default;
268
269 // Reuse construstors from base.
270 using base_type_t::base_type_t;
271
273 self_type_t &
274 set_body( writable_item_t body ) &
275 {
276 auto size = body.size();
277 return set_body_impl( body, size );
278 }
279
281 self_type_t &&
282 set_body( writable_item_t body ) &&
283 {
284 return std::move( this->set_body( std::move( body ) ) );
285 }
286
288 self_type_t &
289 append_body( writable_item_t body_part ) &
290 {
291 auto size = body_part.size();
292 return append_body_impl( body_part, size );
293 }
294
296 self_type_t &&
297 append_body( writable_item_t body_part ) &&
298 {
299 return std::move( this->append_body( std::move( body_part ) ) );
300 }
301
303 request_handling_status_t
304 done( write_status_cb_t wscb = write_status_cb_t{} )
305 {
306 if( m_connection )
307 {
308 const response_output_flags_t
309 response_output_flags{
310 response_parts_attr_t::final_parts,
311 response_connection_attr( m_header.should_keep_alive() ) };
312
313 m_header.content_length( m_body_size );
314
315 if_neccessary_reserve_first_element_for_header();
316
317 m_response_parts[ 0 ] =
318 writable_item_t{ impl::create_header_string( m_header ) };
319
320 write_group_t wg{ std::move( m_response_parts ) };
321 wg.status_line_size( calculate_status_line_size() );
322
323 if( wscb )
324 {
325 wg.after_write_notificator( std::move( wscb ) );
326 }
327
328 auto conn = std::move( m_connection );
329
330 conn->write_response_parts(
331 m_request_id,
332 response_output_flags,
333 std::move( wg ) );
334 }
335 else
336 {
337 throw_done_must_be_called_once();
338 }
339
340 return restinio::request_accepted();
341 }
342
343 private:
344 self_type_t &
345 set_body_impl( writable_item_t & body, std::size_t body_size )
346 {
347 if_neccessary_reserve_first_element_for_header();
348
349 // Leave only buf that is reserved for header,
350 // so forget all the previous data.
351 m_response_parts.resize( 1 );
352
353 if( 0 < body_size )
354 {
355 m_response_parts.emplace_back( std::move( body ) );
356 }
357
358 m_body_size = body_size;
359
360 return *this;
361 }
362
363 self_type_t &
364 append_body_impl( writable_item_t & body_part, std::size_t append_size )
365 {
366 if_neccessary_reserve_first_element_for_header();
367
368 if( 0 < append_size )
369 {
370 m_response_parts.emplace_back( std::move( body_part ) );
371 m_body_size += append_size;
372 }
373
374 return *this;
375 }
376
377 void
378 if_neccessary_reserve_first_element_for_header()
379 {
380 if( m_response_parts.empty() )
381 {
382 m_response_parts.reserve( 2 );
383 m_response_parts.emplace_back();
384 }
385 }
386
387 std::size_t m_body_size{ 0 };
388 writable_items_container_t m_response_parts;
389};
390
392 struct user_controlled_output_t {};
393
395
401 template <>
402 class response_builder_t< user_controlled_output_t > final
403 : public base_response_builder_t< response_builder_t< user_controlled_output_t > >
404{
405 public:
406 using base_type_t =
407 base_response_builder_t< response_builder_t< user_controlled_output_t > >;
408 using self_type_t =
409 response_builder_t< user_controlled_output_t >;
410
411 response_builder_t( response_builder_t && ) = default;
412
413 // Reuse construstors from base.
414 using base_type_t::base_type_t;
415
417 self_type_t &
418 set_content_length( std::size_t content_length ) &
419 {
420 m_header.content_length( content_length );
421 return *this;
422 }
423
425 self_type_t &&
426 set_content_length( std::size_t content_length ) &&
427 {
428 return std::move( this->set_content_length( content_length ) );
429 }
430
432 self_type_t &
433 set_body( writable_item_t body ) &
434 {
435 auto size = body.size();
436 return set_body_impl( body, size );
437 }
438
440 self_type_t &&
441 set_body( writable_item_t body ) &&
442 {
443 return std::move( this->set_body( std::move( body ) ) );
444 }
445
447 self_type_t &
448 append_body( writable_item_t body_part ) &
449 {
450 auto size = body_part.size();
451
452 if( 0 == size )
453 return *this;
454
455 return append_body_impl( body_part );
456 }
457
459 self_type_t &&
460 append_body( writable_item_t body_part ) &&
461 {
462 return std::move( this->append_body( std::move( body_part ) ) );
463 }
464
466
469 self_type_t &
470 flush( write_status_cb_t wscb = write_status_cb_t{} ) &
471 {
472 if( m_connection )
473 {
474 send_ready_data(
475 m_connection,
476 response_parts_attr_t::not_final_parts,
477 std::move( wscb ) );
478 }
479
480 return *this;
481 }
482
484 self_type_t &&
485 flush( write_status_cb_t wscb = write_status_cb_t{} ) &&
486 {
487 return std::move( this->flush( std::move( wscb ) ) );
488 }
489
491 request_handling_status_t
492 done( write_status_cb_t wscb = write_status_cb_t{} )
493 {
494 if( m_connection )
495 {
496 // Note: m_connection should become empty after return
497 // from that method.
498 impl::connection_handle_t old_conn_handle{
499 std::move(m_connection) };
500 send_ready_data(
501 old_conn_handle,
502 response_parts_attr_t::final_parts,
503 std::move( wscb ) );
504 }
505 else
506 {
507 throw_done_must_be_called_once();
508 }
509
510 return restinio::request_accepted();
511 }
512
513 private:
514 void
515 send_ready_data(
516 const impl::connection_handle_t & conn,
517 response_parts_attr_t response_parts_attr,
518 write_status_cb_t wscb )
519 {
520 std::size_t status_line_size{ 0 };
521
522 if( !m_header_was_sent )
523 {
524 m_should_keep_alive_when_header_was_sent =
525 m_header.should_keep_alive();
526
527 if_neccessary_reserve_first_element_for_header();
528
529 m_response_parts[ 0 ] =
530 writable_item_t{ impl::create_header_string( m_header ) };
531
532 m_header_was_sent = true;
533 status_line_size = calculate_status_line_size();
534 }
535
536 if( !m_response_parts.empty() ||
537 wscb ||
538 response_parts_attr_t::final_parts == response_parts_attr )
539 {
540 const response_output_flags_t
541 response_output_flags{
542 response_parts_attr,
543 response_connection_attr( m_should_keep_alive_when_header_was_sent ) };
544
545 write_group_t wg{ std::move( m_response_parts ) };
546 wg.status_line_size( status_line_size );
547
548 if( wscb )
549 {
550 wg.after_write_notificator( std::move( wscb ) );
551 }
552
553 conn->write_response_parts(
554 m_request_id,
555 response_output_flags,
556 std::move( wg ) );
557 }
558 }
559
560 self_type_t &
561 set_body_impl( writable_item_t & body, std::size_t body_size )
562 {
563 if_neccessary_reserve_first_element_for_header();
564
565 // Leave only buf that is reserved for header,
566 // so forget all the previous data.
567 if( !m_header_was_sent )
568 m_response_parts.resize( 1 );
569 else
570 m_response_parts.resize( 0 );
571
572 if( 0 < body_size )
573 {
574 // if body is not empty:
575 m_response_parts.emplace_back( std::move( body ) );
576 }
577
578 return *this;
579 }
580
581 self_type_t &
582 append_body_impl( writable_item_t & body_part )
583 {
584 if_neccessary_reserve_first_element_for_header();
585
586 m_response_parts.emplace_back( std::move( body_part ) );
587 return *this;
588 }
589
590 void
591 if_neccessary_reserve_first_element_for_header()
592 {
593 if( !m_header_was_sent && m_response_parts.empty() )
594 {
595 m_response_parts.reserve( 2 );
596 m_response_parts.emplace_back();
597 }
598 }
599
600
602 bool m_header_was_sent{ false };
603
606
611 bool m_should_keep_alive_when_header_was_sent{ true };
612
614
618 writable_items_container_t m_response_parts;
619};
620
622 struct chunked_output_t {};
623
625
629 template <>
630 class response_builder_t< chunked_output_t > final
631 : public base_response_builder_t< response_builder_t< chunked_output_t > >
632{
633 public:
634 using base_type_t =
635 base_response_builder_t< response_builder_t< chunked_output_t > >;
636 using self_type_t =
637 response_builder_t< chunked_output_t >;
638
639 response_builder_t(
640 http_status_line_t status_line,
641 impl::connection_handle_t connection,
642 request_id_t request_id,
643 bool should_keep_alive )
644 : base_type_t{
645 std::move( status_line ),
646 std::move( connection ),
647 request_id,
648 should_keep_alive }
649 {
650 m_chunks.reserve( 4 );
651 }
652
653 response_builder_t( response_builder_t && ) = default;
654
656 self_type_t &
657 append_chunk( writable_item_t chunk ) &
658 {
659 auto size = chunk.size();
660
661 if( 0 != size )
662 m_chunks.emplace_back( std::move( chunk ) );
663
664 return *this;
665 }
666
668 self_type_t &&
669 append_chunk( writable_item_t chunk ) &&
670 {
671 return std::move( this->append_chunk( std::move( chunk ) ) );
672 }
673
675
678 self_type_t &
679 flush( write_status_cb_t wscb = write_status_cb_t{} ) &
680 {
681 if( m_connection )
682 {
683 send_ready_data(
684 m_connection,
685 response_parts_attr_t::not_final_parts,
686 std::move( wscb ) );
687 }
688
689 return *this;
690 }
691
693 self_type_t &&
694 flush( write_status_cb_t wscb = write_status_cb_t{} ) &&
695 {
696 return std::move( this->flush( std::move( wscb ) ) );
697 }
698
700 request_handling_status_t
701 done( write_status_cb_t wscb = write_status_cb_t{} )
702 {
703 if( m_connection )
704 {
705 // Note: m_connection should become empty after return
706 // from that method.
707 impl::connection_handle_t old_conn_handle{
708 std::move(m_connection) };
709 send_ready_data(
710 old_conn_handle,
711 response_parts_attr_t::final_parts,
712 std::move( wscb ) );
713 }
714 else
715 {
716 throw_done_must_be_called_once();
717 }
718
719 return restinio::request_accepted();
720 }
721
722 private:
723 void
724 send_ready_data(
725 const impl::connection_handle_t & conn,
726 response_parts_attr_t response_parts_attr,
727 write_status_cb_t wscb )
728 {
729 std::size_t status_line_size{ 0 };
730 if( !m_header_was_sent )
731 {
732 status_line_size = calculate_status_line_size();
733 prepare_header_for_sending();
734 }
735
736 auto bufs = create_bufs( response_parts_attr_t::final_parts == response_parts_attr );
737 m_header_was_sent = true;
738
739 const response_output_flags_t
740 response_output_flags{
741 response_parts_attr,
742 response_connection_attr( m_should_keep_alive_when_header_was_sent ) };
743
744 // We have buffers or at least we have after-write notificator.
745 if( !bufs.empty() || wscb )
746 {
747 write_group_t wg{ std::move( bufs ) };
748 wg.status_line_size( status_line_size );
749
750 if( wscb )
751 {
752 wg.after_write_notificator( std::move( wscb ) );
753 }
754
755 conn->write_response_parts(
756 m_request_id,
757 response_output_flags,
758 std::move( wg ) );
759 }
760 }
761
762 void
763 prepare_header_for_sending()
764 {
765 m_should_keep_alive_when_header_was_sent =
766 m_header.should_keep_alive();
767
768 constexpr const char value[] = "chunked";
769 if( !m_header.has_field( restinio::http_field::transfer_encoding ) )
770 {
771 m_header.add_field(
772 restinio::http_field::transfer_encoding,
773 std::string{ value, impl::ct_string_len( value ) } );
774 }
775 else
776 {
777 auto & current_value =
778 m_header.get_field( restinio::http_field::transfer_encoding );
779 if( std::string::npos == current_value.find( value ) )
780 {
781 constexpr const char comma_value[] = ",chunked";
782 m_header.append_field(
783 restinio::http_field::transfer_encoding,
784 std::string{
785 comma_value,
786 impl::ct_string_len( comma_value ) } );
787 }
788 }
789 }
790
791 writable_items_container_t
792 create_bufs( bool add_zero_chunk )
793 {
794 writable_items_container_t bufs;
795
796 std::size_t reserve_size = 2 * m_chunks.size() + 1;
797
798 if( !m_header_was_sent )
799 {
800 ++reserve_size;
801 }
802 if( add_zero_chunk )
803 {
804 ++reserve_size;
805 }
806
807 bufs.reserve( reserve_size );
808
809 if( !m_header_was_sent )
810 {
811 bufs.emplace_back(
812 impl::create_header_string(
813 m_header,
814 impl::content_length_field_presence_t::skip_content_length ) );
815 }
816
817 // Since fmtlib-8.0.0 compile-time checks of format strings
818 // is enabled by default. If non-constexpr string has to be
819 // passed as format_string then fmt::runtime() function should
820 // be used. But there are some drawbacks:
821 // - fmt::runtime is added only in fmtlib-8.0.0, there is no
822 // such a function in previous versions of fmtlib;
823 // - using fmt::runtime we lack a possibility to check
824 // format_string in compile-time and can have some performance
825 // penalty in run-time.
826 //
827 // Because of that, the following code was rewritten to have different
828 // code fragments for the first item in m_chunks and all successive
829 // items.
830 auto chunk_it = m_chunks.begin();
831 const auto chunk_end = m_chunks.end();
832 if( chunk_it != chunk_end )
833 {
834 bufs.emplace_back(
835 fmt::format(
836 "{:X}\r\n",
837 asio_ns::buffer_size( chunk_it->buf() ) ) );
838 bufs.emplace_back( std::move( *chunk_it ) );
839
840 for( ++chunk_it; chunk_it != chunk_end; ++chunk_it )
841 {
842 bufs.emplace_back(
843 fmt::format(
844 "\r\n{:X}\r\n",
845 asio_ns::buffer_size( chunk_it->buf() ) ) );
846 bufs.emplace_back( std::move( *chunk_it ) );
847 }
848 }
849
850 const char * const ending_representation = "\r\n" "0\r\n\r\n";
851 const char * appendix_begin = ending_representation + 2;
852 const char * appendix_end = appendix_begin;
853
854 if( !m_chunks.empty() )
855 {
856 // Add "\r\n"part to appendix.
857 appendix_begin -= 2;
858 // bufs.emplace_back( const_buffer( rn_ending, 2 ) );
859 }
860
861 if( add_zero_chunk )
862 {
863 // Add "0\r\n\r\n"part to appendix.
864 appendix_end += 5;
865 }
866
867 if( appendix_begin != appendix_end )
868 {
869 bufs.emplace_back( const_buffer(
870 appendix_begin,
871 static_cast<std::size_t>(appendix_end - appendix_begin)
872 ) );
873 }
874
875 m_chunks.clear();
876
877 return bufs;
878 }
879
881 bool m_header_was_sent{ false };
882
885
890 bool m_should_keep_alive_when_header_was_sent{ true };
891
893 writable_items_container_t m_chunks;
894};
895
896} /* namespace restinio */
897
restinio::base_response_builder_t
Definition: message_builders.hpp:60
restinio::base_response_builder_t::upcast_reference
Response_Builder & upcast_reference() noexcept
Definition: message_builders.hpp:230
restinio::base_response_builder_t::append_header
Response_Builder && append_header(http_field_t field_id, std::string field_value) &&
Add header field.
Definition: message_builders.hpp:150
restinio::base_response_builder_t::append_header
Response_Builder && append_header(http_header_field_t http_header_field) &&
Add header field.
Definition: message_builders.hpp:130
restinio::base_response_builder_t::m_connection
impl::connection_handle_t m_connection
Definition: message_builders.hpp:219
restinio::base_response_builder_t::append_header
Response_Builder && append_header(std::string field_name, std::string field_value) &&
Add header field.
Definition: message_builders.hpp:111
restinio::base_response_builder_t::append_header
Response_Builder & append_header(std::string field_name, std::string field_value) &
Add header field.
Definition: message_builders.hpp:99
restinio::base_response_builder_t::connection_close
Response_Builder & connection_close() &noexcept
Set connection close.
Definition: message_builders.hpp:181
restinio::base_response_builder_t::calculate_status_line_size
std::size_t calculate_status_line_size() const noexcept
Definition: message_builders.hpp:211
restinio::base_response_builder_t::base_response_builder_t
base_response_builder_t(base_response_builder_t &&) noexcept=default
restinio::base_response_builder_t::append_header
Response_Builder & append_header(http_header_field_t http_header_field) &
Add header field.
Definition: message_builders.hpp:122
restinio::base_response_builder_t::append_header
Response_Builder & append_header(http_field_t field_id, std::string field_value) &
Add header field.
Definition: message_builders.hpp:138
restinio::base_response_builder_t::connection_keep_alive
Response_Builder & connection_keep_alive() &noexcept
Set connection keep-alive.
Definition: message_builders.hpp:197
restinio::base_response_builder_t::header
const http_response_header_t & header() const noexcept
Definition: message_builders.hpp:91
restinio::base_response_builder_t::append_header_date_field
Response_Builder & append_header_date_field(std::chrono::system_clock::time_point tp=std::chrono::system_clock::now()) &
Add header Date field.
Definition: message_builders.hpp:162
restinio::base_response_builder_t::m_request_id
const request_id_t m_request_id
Definition: message_builders.hpp:220
restinio::base_response_builder_t::append_header_date_field
Response_Builder && append_header_date_field(std::chrono::system_clock::time_point tp=std::chrono::system_clock::now()) &&
Add header Date field.
Definition: message_builders.hpp:172
restinio::base_response_builder_t::operator=
base_response_builder_t & operator=(const base_response_builder_t &)=delete
restinio::base_response_builder_t::base_response_builder_t
base_response_builder_t(const base_response_builder_t &)=delete
restinio::base_response_builder_t::header
http_response_header_t & header() noexcept
Accessors for header.
Definition: message_builders.hpp:85
restinio::base_response_builder_t::connection_close
Response_Builder && connection_close() &&noexcept
Set connection close.
Definition: message_builders.hpp:189
restinio::base_response_builder_t::connection_keep_alive
Response_Builder && connection_keep_alive() &&noexcept
Definition: message_builders.hpp:204
restinio::base_response_builder_t::m_header
http_response_header_t m_header
Definition: message_builders.hpp:217
restinio::base_response_builder_t::throw_done_must_be_called_once
void throw_done_must_be_called_once() const
Definition: message_builders.hpp:223
restinio::exception_t
Exception class for all exceptions thrown by RESTinio.
Definition: exception.hpp:26
restinio::http_header_field_t
A single header field.
Definition: http_headers.hpp:583
restinio::http_header_fields_t::add_field
void add_field(http_field_t field_id, std::string field_value)
Add a field in the form of id-value pair.
Definition: http_headers.hpp:860
restinio::http_header_fields_t::set_field
void set_field(http_header_field_t http_header_field)
Set header field via http_header_field_t.
Definition: http_headers.hpp:773
restinio::http_status_line_t
HTTP response header status line.
Definition: http_headers.hpp:2124
restinio::http_status_line_t::reason_phrase
const std::string & reason_phrase() const noexcept
Definition: http_headers.hpp:2145
restinio::response_builder_t< chunked_output_t >
Chunked transfer encoding output builder.
Definition: message_builders.hpp:632
restinio::response_builder_t< chunked_output_t >::flush
self_type_t & flush(write_status_cb_t wscb=write_status_cb_t{}) &
Flush ready outgoing data.
Definition: message_builders.hpp:679
restinio::response_builder_t< chunked_output_t >::flush
self_type_t && flush(write_status_cb_t wscb=write_status_cb_t{}) &&
Flush ready outgoing data.
Definition: message_builders.hpp:694
restinio::response_builder_t< chunked_output_t >::m_chunks
writable_items_container_t m_chunks
Chunks accumulator.
Definition: message_builders.hpp:893
restinio::response_builder_t< chunked_output_t >::create_bufs
writable_items_container_t create_bufs(bool add_zero_chunk)
Definition: message_builders.hpp:792
restinio::response_builder_t< chunked_output_t >::send_ready_data
void send_ready_data(const impl::connection_handle_t &conn, response_parts_attr_t response_parts_attr, write_status_cb_t wscb)
Definition: message_builders.hpp:724
restinio::response_builder_t< chunked_output_t >::response_builder_t
response_builder_t(response_builder_t &&)=default
restinio::response_builder_t< chunked_output_t >::prepare_header_for_sending
void prepare_header_for_sending()
Definition: message_builders.hpp:763
restinio::response_builder_t< chunked_output_t >::append_chunk
self_type_t && append_chunk(writable_item_t chunk) &&
Append current chunk.
Definition: message_builders.hpp:669
restinio::response_builder_t< chunked_output_t >::append_chunk
self_type_t & append_chunk(writable_item_t chunk) &
Append current chunk.
Definition: message_builders.hpp:657
restinio::response_builder_t< chunked_output_t >::done
request_handling_status_t done(write_status_cb_t wscb=write_status_cb_t{})
Complete response.
Definition: message_builders.hpp:701
restinio::response_builder_t< chunked_output_t >::response_builder_t
response_builder_t(http_status_line_t status_line, impl::connection_handle_t connection, request_id_t request_id, bool should_keep_alive)
Definition: message_builders.hpp:639
restinio::response_builder_t< restinio_controlled_output_t >
Simple standard response builder.
Definition: message_builders.hpp:260
restinio::response_builder_t< restinio_controlled_output_t >::append_body_impl
self_type_t & append_body_impl(writable_item_t &body_part, std::size_t append_size)
Definition: message_builders.hpp:364
restinio::response_builder_t< restinio_controlled_output_t >::m_response_parts
writable_items_container_t m_response_parts
Definition: message_builders.hpp:388
restinio::response_builder_t< restinio_controlled_output_t >::append_body
self_type_t && append_body(writable_item_t body_part) &&
Append body.
Definition: message_builders.hpp:297
restinio::response_builder_t< restinio_controlled_output_t >::append_body
self_type_t & append_body(writable_item_t body_part) &
Append body.
Definition: message_builders.hpp:289
restinio::response_builder_t< restinio_controlled_output_t >::if_neccessary_reserve_first_element_for_header
void if_neccessary_reserve_first_element_for_header()
Definition: message_builders.hpp:378
restinio::response_builder_t< restinio_controlled_output_t >::response_builder_t
response_builder_t(response_builder_t &&)=default
restinio::response_builder_t< restinio_controlled_output_t >::done
request_handling_status_t done(write_status_cb_t wscb=write_status_cb_t{})
Complete response.
Definition: message_builders.hpp:304
restinio::response_builder_t< restinio_controlled_output_t >::set_body
self_type_t && set_body(writable_item_t body) &&
Set body.
Definition: message_builders.hpp:282
restinio::response_builder_t< restinio_controlled_output_t >::set_body_impl
self_type_t & set_body_impl(writable_item_t &body, std::size_t body_size)
Definition: message_builders.hpp:345
restinio::response_builder_t< restinio_controlled_output_t >::set_body
self_type_t & set_body(writable_item_t body) &
Set body.
Definition: message_builders.hpp:274
restinio::response_builder_t< user_controlled_output_t >
User controlled response output builder.
Definition: message_builders.hpp:404
restinio::response_builder_t< user_controlled_output_t >::flush
self_type_t & flush(write_status_cb_t wscb=write_status_cb_t{}) &
Flush ready outgoing data.
Definition: message_builders.hpp:470
restinio::response_builder_t< user_controlled_output_t >::m_response_parts
writable_items_container_t m_response_parts
Body accumulator.
Definition: message_builders.hpp:618
restinio::response_builder_t< user_controlled_output_t >::append_body_impl
self_type_t & append_body_impl(writable_item_t &body_part)
Definition: message_builders.hpp:582
restinio::response_builder_t< user_controlled_output_t >::set_body
self_type_t & set_body(writable_item_t body) &
Set body (part).
Definition: message_builders.hpp:433
restinio::response_builder_t< user_controlled_output_t >::response_builder_t
response_builder_t(response_builder_t &&)=default
restinio::response_builder_t< user_controlled_output_t >::send_ready_data
void send_ready_data(const impl::connection_handle_t &conn, response_parts_attr_t response_parts_attr, write_status_cb_t wscb)
Definition: message_builders.hpp:515
restinio::response_builder_t< user_controlled_output_t >::set_content_length
self_type_t & set_content_length(std::size_t content_length) &
Manualy set content length.
Definition: message_builders.hpp:418
restinio::response_builder_t< user_controlled_output_t >::set_content_length
self_type_t && set_content_length(std::size_t content_length) &&
Manualy set content length.
Definition: message_builders.hpp:426
restinio::response_builder_t< user_controlled_output_t >::set_body
self_type_t && set_body(writable_item_t body) &&
Set body (part).
Definition: message_builders.hpp:441
restinio::response_builder_t< user_controlled_output_t >::flush
self_type_t && flush(write_status_cb_t wscb=write_status_cb_t{}) &&
Flush ready outgoing data.
Definition: message_builders.hpp:485
restinio::response_builder_t< user_controlled_output_t >::done
request_handling_status_t done(write_status_cb_t wscb=write_status_cb_t{})
Complete response.
Definition: message_builders.hpp:492
restinio::response_builder_t< user_controlled_output_t >::set_body_impl
self_type_t & set_body_impl(writable_item_t &body, std::size_t body_size)
Definition: message_builders.hpp:561
restinio::response_builder_t< user_controlled_output_t >::if_neccessary_reserve_first_element_for_header
void if_neccessary_reserve_first_element_for_header()
Definition: message_builders.hpp:591
restinio::response_builder_t< user_controlled_output_t >::append_body
self_type_t && append_body(writable_item_t body_part) &&
Append body.
Definition: message_builders.hpp:460
restinio::response_builder_t< user_controlled_output_t >::append_body
self_type_t & append_body(writable_item_t body_part) &
Append body.
Definition: message_builders.hpp:448
restinio::response_builder_t
Forbid arbitrary response_builder_t instantiations.
Definition: message_builders.hpp:243
restinio::response_builder_t::response_builder_t
response_builder_t()=delete
restinio::writable_item_t
Class for storing the buffers used for streaming body (request/response).
Definition: buffers.hpp:496
restinio::write_group_t
Group of writable items transported to the context of underlying connection as one solid piece.
Definition: buffers.hpp:692
common_types.hpp
connection_base.hpp
header_helpers.hpp
http_headers.hpp
include_fmtlib.hpp
A special wrapper around fmtlib include files.
nonstd::optional_lite::std11::move
T & move(T &t)
Definition: optional.hpp:465
restinio::impl::create_header_string
std::string create_header_string(const http_response_header_t &h, content_length_field_presence_t content_length_field_presence=content_length_field_presence_t::add_content_length, std::size_t buffer_size=0)
Creates a string for http response header.
Definition: header_helpers.hpp:68
restinio::impl::connection_handle_t
std::shared_ptr< connection_base_t > connection_handle_t
Alias for http connection handle.
Definition: connection_base.hpp:47
restinio::impl::content_length_field_presence_t::skip_content_length
@ skip_content_length
restinio::impl::ct_string_len
constexpr std::size_t ct_string_len(const char(&)[N]) noexcept
Compile time c-string length.
Definition: header_helpers.hpp:28
restinio
Definition: asio_include.hpp:21
restinio::writable_items_container_t
std::vector< writable_item_t > writable_items_container_t
Definition: buffers.hpp:668
restinio::request_id_t
unsigned int request_id_t
Request id in scope of single connection.
Definition: common_types.hpp:70
restinio::response_connection_attr
response_connection_attr_t response_connection_attr(bool should_keep_alive)
Definition: common_types.hpp:113
restinio::request_handling_status_t
request_handling_status_t
Request handling status.
Definition: common_types.hpp:26
restinio::http_field_t
http_field_t
C++ enum that repeats nodejs c-style enum.
Definition: http_headers.hpp:233
restinio::write_status_cb_t
std::function< void(const asio_ns::error_code &ec) > write_status_cb_t
An alias for a callback to be invoked after the write operation of a particular group of "buffers".
Definition: buffers.hpp:680
restinio::make_date_field_value
std::string make_date_field_value(std::time_t t)
Format a timepoint to a string of a propper format.
Definition: message_builders.hpp:33
restinio::const_buffer
constexpr const_buffer_t const_buffer(const void *str, std::size_t size) noexcept
Definition: buffers.hpp:424
restinio::request_accepted
RESTINIO_NODISCARD constexpr request_handling_status_t request_accepted() noexcept
Definition: common_types.hpp:46
restinio::response_parts_attr_t
response_parts_attr_t
Attribute for parts.
Definition: common_types.hpp:74
restinio::response_parts_attr_t::final_parts
@ final_parts
Final parts (response ands with these parts).
restinio::response_parts_attr_t::not_final_parts
@ not_final_parts
Intermediate parts (more parts of response to follow).
std
STL namespace.
os.hpp
make_gmtime
std::tm make_gmtime(std::time_t t)
Definition: os_posix.ipp:2
sendfile.hpp
restinio::chunked_output_t
Tag type for chunked output response builder.
Definition: message_builders.hpp:622
restinio::http_header_common_t::should_keep_alive
bool should_keep_alive() const noexcept
Definition: http_headers.hpp:1611
restinio::http_response_header_t
Resp header.
Definition: http_headers.hpp:2338
restinio::http_response_header_t::status_line
const http_status_line_t & status_line() const noexcept
Definition: http_headers.hpp:2364
restinio::response_output_flags_t
Response output flags for buffers commited to response-coordinator.
Definition: common_types.hpp:123
restinio::restinio_controlled_output_t
Tag type for RESTinio controlled output response builder.
Definition: message_builders.hpp:248
restinio::user_controlled_output_t
Tag type for user controlled output response builder.
Definition: message_builders.hpp:392
const
#define const
Definition: zconf.h:230