diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f8e5888..59bbef07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ API Changes: * Remove `opcode` from `read`, `async_read` * `read_frame` returns `bool` fin * `opcode` is private +* finish(error_code&) is a BodyReader requirement Actions Required: diff --git a/doc/concept/BodyReader.qbk b/doc/concept/BodyReader.qbk index 89907f17..0d320085 100644 --- a/doc/concept/BodyReader.qbk +++ b/doc/concept/BodyReader.qbk @@ -91,6 +91,14 @@ In this table: or `false` if the buffer returned on this call is the last buffer representing the body. ] +][ + [`a.finish(ec)`] + [] + [ + This function is called after the reader indicates there + are no more buffers remaining. + If `ec` is set, the error will be propagated to the caller. + ] ][ [`is_body_reader`] [`std::true_type`] @@ -155,9 +163,18 @@ public: A value of `false` means there is no more body data. @li If `ec` contains an error code, the return value is ignored. + + @param ec Set to the error, if any occurred. */ boost::optional> get(error_code& ec); + + /** Called after `get` indicates there are no more buffers. + + @param ec Set to the error, if any occurred. + */ + void + finish(error_code& ec); }; ``` diff --git a/examples/file_body.hpp b/examples/file_body.hpp index 6b9f96cd..a0d9505c 100644 --- a/examples/file_body.hpp +++ b/examples/file_body.hpp @@ -90,6 +90,11 @@ struct file_body offset_ += nread; return {{const_buffers_type{buf_, nread}, offset_ < size_}}; } + + void + finish(error_code&) + { + } }; }; diff --git a/include/beast/http/buffer_body.hpp b/include/beast/http/buffer_body.hpp index 1f6fc1f1..9932f7c0 100644 --- a/include/beast/http/buffer_body.hpp +++ b/include/beast/http/buffer_body.hpp @@ -137,6 +137,11 @@ struct buffer_body ec = error::need_buffer; return boost::none; } + + void + finish(error_code&) + { + } }; #endif diff --git a/include/beast/http/dynamic_body.hpp b/include/beast/http/dynamic_body.hpp index ffaddebb..83d7050b 100644 --- a/include/beast/http/dynamic_body.hpp +++ b/include/beast/http/dynamic_body.hpp @@ -70,6 +70,11 @@ struct basic_dynamic_body { return {{body_.data(), false}}; } + + void + finish(error_code&) + { + } }; #endif diff --git a/include/beast/http/empty_body.hpp b/include/beast/http/empty_body.hpp index 60575b17..b4f1fe21 100644 --- a/include/beast/http/empty_body.hpp +++ b/include/beast/http/empty_body.hpp @@ -72,6 +72,11 @@ struct empty_body { return boost::none; } + + void + finish(error_code&) + { + } }; #endif diff --git a/include/beast/http/impl/serializer.ipp b/include/beast/http/impl/serializer.ipp index 0a226864..b0691d37 100644 --- a/include/beast/http/impl/serializer.ipp +++ b/include/beast/http/impl/serializer.ipp @@ -250,6 +250,10 @@ get(error_code& ec, Visit&& visit) break; go_complete: + if(rd_) + rd_->finish(ec); + if(ec) + return; s_ = do_complete; break; } diff --git a/include/beast/http/string_body.hpp b/include/beast/http/string_body.hpp index a960ee58..04737091 100644 --- a/include/beast/http/string_body.hpp +++ b/include/beast/http/string_body.hpp @@ -73,6 +73,11 @@ struct string_body return {{const_buffers_type{ body_.data(), body_.size()}, false}}; } + + void + finish(error_code&) + { + } }; #endif diff --git a/include/beast/http/type_traits.hpp b/include/beast/http/type_traits.hpp index 7ae997a1..52f315ff 100644 --- a/include/beast/http/type_traits.hpp +++ b/include/beast/http/type_traits.hpp @@ -83,6 +83,7 @@ struct is_body_reader>&>() = std::declval().get(std::declval()), + std::declval().finish(std::declval()), (void)0)>> : std::integral_constant::value && diff --git a/test/http/write.cpp b/test/http/write.cpp index 564ed892..3d8d6db9 100644 --- a/test/http/write.cpp +++ b/test/http/write.cpp @@ -65,6 +65,11 @@ public: return {{const_buffers_type{ body_.data(), body_.size()}, false}}; } + + void + finish(error_code&) + { + } }; }; @@ -115,6 +120,11 @@ public: std::integral_constant{}); } + void + finish(error_code&) + { + } + private: boost::optional> get( @@ -253,6 +263,12 @@ public: return {{const_buffers_type{ body_.s_.data() + n_++, 1}, true}}; } + + void + finish(error_code& ec) + { + body_.fc_.fail(ec); + } }; };