This is an automated email from the ASF dual-hosted git repository.

maskit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 58e143034e Add HTTP/3 POST request handling (#9766)
58e143034e is described below

commit 58e143034e0ee5a231a42427e3080454818e2f4d
Author: Masakazu Kitajo <[email protected]>
AuthorDate: Tue Jun 6 00:19:39 2023 +0900

    Add HTTP/3 POST request handling (#9766)
---
 proxy/http3/Http3StreamDataVIOAdaptor.cc | 29 ++++++++++++++++++++++++-----
 proxy/http3/Http3StreamDataVIOAdaptor.h  |  3 +++
 proxy/http3/Http3Transaction.cc          | 26 ++++++++++++++++++++++++--
 3 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/proxy/http3/Http3StreamDataVIOAdaptor.cc 
b/proxy/http3/Http3StreamDataVIOAdaptor.cc
index 15712e1c5c..cb154d8ab8 100644
--- a/proxy/http3/Http3StreamDataVIOAdaptor.cc
+++ b/proxy/http3/Http3StreamDataVIOAdaptor.cc
@@ -24,7 +24,12 @@
 #include "Http3StreamDataVIOAdaptor.h"
 #include "I_VIO.h"
 
-Http3StreamDataVIOAdaptor::Http3StreamDataVIOAdaptor(VIO *sink) : 
_sink_vio(sink) {}
+Http3StreamDataVIOAdaptor::Http3StreamDataVIOAdaptor(VIO *sink) : 
_sink_vio(sink), _buffer(new_MIOBuffer(BUFFER_SIZE_INDEX_4K)) {}
+
+Http3StreamDataVIOAdaptor::~Http3StreamDataVIOAdaptor()
+{
+  free_MIOBuffer(this->_buffer);
+}
 
 std::vector<Http3FrameType>
 Http3StreamDataVIOAdaptor::interests()
@@ -38,10 +43,8 @@ 
Http3StreamDataVIOAdaptor::handle_frame(std::shared_ptr<const Http3Frame> frame)
   ink_assert(frame->type() == Http3FrameType::DATA);
   const Http3DataFrame *dframe = dynamic_cast<const Http3DataFrame 
*>(frame.get());
 
-  SCOPED_MUTEX_LOCK(lock, this->_sink_vio->mutex, this_ethread());
-
-  MIOBuffer *writer = this->_sink_vio->get_writer();
-  writer->write(dframe->payload(), dframe->payload_length());
+  // Need to wait for headers to be written
+  this->_buffer->write(dframe->payload(), dframe->payload_length());
   this->_total_data_length += dframe->payload_length();
 
   return Http3ErrorUPtr(new Http3NoError());
@@ -50,5 +53,21 @@ 
Http3StreamDataVIOAdaptor::handle_frame(std::shared_ptr<const Http3Frame> frame)
 void
 Http3StreamDataVIOAdaptor::finalize()
 {
+  SCOPED_MUTEX_LOCK(lock, this->_sink_vio->mutex, this_ethread());
+  MIOBuffer *writer      = this->_sink_vio->get_writer();
+  IOBufferReader *reader = this->_buffer->alloc_reader();
+  IOBufferBlock *block;
+  while (reader->read_avail() > 0 && (block = reader->get_current_block()) != 
nullptr) {
+    writer->append_block(block);
+    reader->consume(block->size());
+  }
+
+  this->_buffer->dealloc_reader(reader);
   this->_sink_vio->nbytes = this->_total_data_length;
 }
+
+bool
+Http3StreamDataVIOAdaptor::has_data()
+{
+  return this->_total_data_length > 0;
+}
diff --git a/proxy/http3/Http3StreamDataVIOAdaptor.h 
b/proxy/http3/Http3StreamDataVIOAdaptor.h
index 19ac384320..5114979cd3 100644
--- a/proxy/http3/Http3StreamDataVIOAdaptor.h
+++ b/proxy/http3/Http3StreamDataVIOAdaptor.h
@@ -31,6 +31,7 @@ class Http3StreamDataVIOAdaptor : public Http3FrameHandler
 {
 public:
   Http3StreamDataVIOAdaptor(VIO *sink);
+  virtual ~Http3StreamDataVIOAdaptor();
 
   // Http3FrameHandler
   std::vector<Http3FrameType> interests() override;
@@ -38,8 +39,10 @@ public:
 
   // Http3StreamDataVIOAdaptor
   void finalize();
+  bool has_data();
 
 private:
   VIO *_sink_vio             = nullptr;
   int64_t _total_data_length = 0;
+  MIOBuffer *_buffer;
 };
diff --git a/proxy/http3/Http3Transaction.cc b/proxy/http3/Http3Transaction.cc
index 1221d99f96..38f64118c1 100644
--- a/proxy/http3/Http3Transaction.cc
+++ b/proxy/http3/Http3Transaction.cc
@@ -582,11 +582,33 @@ Http3Transaction::_process_write_vio()
   return nwritten;
 }
 
-// TODO:  Just a place holder for now
 bool
 Http3Transaction::has_request_body(int64_t content_length, bool 
is_chunked_set) const
 {
-  return false;
+  // Has body if Content-Length != 0
+  if (content_length != 0) {
+    return true;
+  }
+
+  // Has body if there is DATA frame received (In case Content-Length is 
omitted)
+  if (this->_data_handler->has_data()) {
+    return true;
+  }
+
+  // No body if stream is already closed and DATA frame is not received yet
+  // TODO stream state
+  // if () {
+  //   return false;
+  // }
+
+  // No body if trailing header is received and DATA frame is not received yet
+  // TODO trailing header
+  // if () {
+  //   return false;
+  // }
+
+  // If the stream is open and trailer header hasn't been received, there may 
be DATA.
+  return true;
 }
 
 //

Reply via email to