Merge: doc: fixed some typos and other misc. corrections
[nit.git] / lib / nitcorn / http_request_buffer.nit
index 9279a11..84fb8ca 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# Http request parsing for bufferized inputs.
+# Http request parsing for buffered inputs.
 module http_request_buffer
 
 intrude import libevent
 
-redef class Connection
+# Connection rebuilding HTTP requests
+#
+# Subclass should refine `read_full_request` and avoid `read_callback`.
+class HTTPConnection
+       super Connection
 
        private var in_request = false
        private var in_header = false
        private var in_body = false
-       private var current_header: FlatBuffer
-       private var current_body: FlatBuffer
+       private var current_header = new Array[Writable]
+       private var current_body = new Array[Writable]
        private var content_length = 0
        private var current_length = 0
 
-       # FIXME will not work if the header/body delimiter fall between two watermarks windows.
-       redef fun read_callback_native(cstr, len)
+       # FIXME will not work if the header/body delimiter falls between two watermarks windows.
+       redef fun read_callback(str)
        do
                # is this the start of a request?
-               if not in_request then
-                       parse_start
-               end
-               var str = cstr.to_s_with_length(len)
+               if not in_request then parse_start
+
                var body: String
                # parsing header
                if in_header then
@@ -42,19 +44,20 @@ redef class Connection
                else
                        body = str
                end
+
                # parsing body
-               if in_body then
-                       parse_body(body)
-               end
+               if in_body then parse_body(body)
        end
 
+       # Callback when a full HTTP request is received
+       fun read_http_request(str: String) do end
 
-       # We have a new request entering
+       # Prepare for a new request
        private fun parse_start do
                in_request = true
                # reset values
-               current_header = new FlatBuffer
-               current_body = new FlatBuffer
+               current_header.clear
+               current_body.clear
                current_length = 0
                content_length = 0
                # next step is to find the header part
@@ -64,17 +67,17 @@ redef class Connection
 
        # We are receiving the header of a request
        #
-       # Return parsed body foud in header window
+       # Return parsed body found in header window
        private fun parse_header(str: String): String do
                # split in CRLF
                var parts = str.split("\r\n\r\n")
                # first part go in the header
-               current_header.append parts.shift
+               current_header.add parts.shift
 
                # if there is more part we are done with headers
                if not parts.is_empty then
                        # get content-length
-                       parse_content_length(current_header.write_to_string)
+                       parse_content_length current_header.join
                        # next step if to parse body
                        in_header = false
                        in_body = true
@@ -97,8 +100,8 @@ redef class Connection
 
        # We are receiving body parts.
        private fun parse_body(str: String) do
-               current_length += str.length
-               current_body.append str
+               current_length += str.byte_length
+               current_body.add str
                if current_length >= content_length then
                        parse_end
                end
@@ -106,11 +109,11 @@ redef class Connection
 
        # We have reached the end of the body
        private fun parse_end do
-               var res = new FlatBuffer
-               res.append current_header
+               var res = new FlatBuffer.with_capacity(content_length)
+               for ch in current_header do res.append ch.write_to_string
                res.append "\r\n\r\n"
-               res.append current_body
-               read_callback(res.write_to_string)
+               for cb in current_body do res.append cb.write_to_string
+               read_http_request res.to_s
                in_request = false
        end
 end