From b6c91052e2f987560dc582d763fbcddacdec545b Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 14 Aug 2014 11:07:05 +0300 Subject: [PATCH] works --- httpd.cc | 22 +++++++++------------- reactor.hh | 18 ++++++++++++------ sstring.hh | 2 +- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/httpd.cc b/httpd.cc index b70a48af20..f5c1f08251 100644 --- a/httpd.cc +++ b/httpd.cc @@ -63,7 +63,6 @@ public: auto start_line = fut_start_line.get(); std::cmatch match; if (!std::regex_match(start_line.begin(), start_line.end(), match, start_line_re)) { - std::cout << "no match\n"; return bad(); } _method = to_sstring(match[1]); @@ -72,7 +71,6 @@ public: if (_method != "GET") { return bad(); } - std::cout << "start line: " << _method << " | " << _url << " | " << _version << "\n"; _read_buf.read_until(limit, '\n').then([this] (future header) { parse_header(std::move(header)); }); @@ -80,22 +78,18 @@ public: } void parse_header(future f_header) { auto header = f_header.get(); - std::cout << ">>>" << sstring(header.begin(), header.end()) << "<<<\n"; if (header.size() == 2 && header[0] == '\r' && header[1] == '\n') { - std::cout << "req end\n"; return generate_response(); } std::cmatch match; if (std::regex_match(header.begin(), header.end(), match, header_re)) { sstring name = to_sstring(match[1]); sstring value = to_sstring(match[2]); - std::cout << "found header: " << name << "=" << value << ".\n"; _headers[name] = std::move(value); _last_header_name = std::move(name); } else if (std::regex_match(header.begin(), header.end(), match, header_cont_re)) { _headers[_last_header_name] += " "; _headers[_last_header_name] += to_sstring(match[1]); - std::cout << "found header: " << _last_header_name << "=" << _headers[_last_header_name] << ".\n"; } else { return bad(); } @@ -108,16 +102,18 @@ public: respond(); } void respond() { - std::cout << "responding\n"; _write_buf.write(_response_line.begin(), _response_line.size()).then( [this] (future n) mutable { write_response_headers(_response_headers.begin()).then( [this] (future done) { - write_body().then( - [this] (future done) { - _write_buf.flush().then( - [this] (future done) { - delete this; + _write_buf.write("\r\n", 2).then( + [this] (future done) mutable { + write_body().then( + [this] (future done) { + _write_buf.flush().then( + [this] (future done) { + delete this; + }); }); }); }); @@ -148,7 +144,7 @@ public: return fut; } void generate_response() { - _response_line = "HTTP/1.1 200 OK\r\n\r\n"; + _response_line = "HTTP/1.1 200 OK\r\n"; _response_headers["Content-Type"] = "text/html"; _response_body = "this is the future

Future!!

"; respond(); diff --git a/reactor.hh b/reactor.hh index 4a62a0f2b7..525233e97a 100644 --- a/reactor.hh +++ b/reactor.hh @@ -110,6 +110,7 @@ struct future_state { abort(); } } + bool available() const { return _state == state::result || _state == state::exception; } bool has_promise() const { return _promise; } bool has_future() const { return _future; } void wait(); @@ -131,7 +132,7 @@ struct future_state { assert(_state == state::future); _state = state::result; new (&_u.value) T(std::forward(a)...); - schedule(); + make_ready(); } void set_exception(std::exception_ptr ex) { assert(_state == state::future); @@ -151,6 +152,9 @@ struct future_state { template void schedule(Func&& func) { _task = make_task(std::forward(func)); + if (available()) { + make_ready(); + } } }; @@ -347,6 +351,7 @@ class input_stream_buffer { size_t _size; size_t _begin = 0; size_t _end = 0; + bool _eof = false; private: using tmp_buf = temporary_buffer; size_t available() const { return _end - _begin; } @@ -524,8 +529,9 @@ void input_stream_buffer::read_until_part(size_t limit, CharType eol, auto to_search = std::min(limit - completed, available()); auto i = std::find(_buf.get() + _begin, _buf.get() + _begin + to_search, eol); auto nr_found = i - (_buf.get() + _begin); - if (i != _buf.get() + _begin + to_search || completed + nr_found == limit) { - std::cout << "read_until_part: found " << nr_found << "\n"; + if (i != _buf.get() + _begin + to_search + || completed + nr_found == limit + || (i == _buf.get() + _end && _eof)) { if (i != _buf.get() + _begin + to_search && completed + nr_found < limit) { assert(*i == eol); ++i; // include eol in result @@ -536,10 +542,8 @@ void input_stream_buffer::read_until_part(size_t limit, CharType eol, } advance(nr_found); completed += nr_found; - std::cout << "fulfilling promise with '" << std::string(out.begin(), out.begin() + completed) << "'\n"; pr.set_value(std::move(out).prefix(completed)); } else { - std::cout << "not found, scheduling again\n"; if (!out.owning() && _end == _size) { // wrapping around, must allocate auto new_out = tmp_buf(limit); @@ -552,7 +556,9 @@ void input_stream_buffer::read_until_part(size_t limit, CharType eol, } _fd.read_some(_buf.get() + _end, _size - _end).then( [this, limit, eol, pr = std::move(pr), out = std::move(out), completed] (future now) mutable { - _end += now.get(); + auto n = now.get(); + _end += n; + _eof = n == 0; read_until_part(limit, eol, std::move(pr), std::move(out), completed); }); } diff --git a/sstring.hh b/sstring.hh index db460c3034..915c5a9f42 100644 --- a/sstring.hh +++ b/sstring.hh @@ -126,7 +126,7 @@ public: } void reset() noexcept { if (is_external()) { - delete u.external.str; + delete[] u.external.str; } u.internal.size = 0; u.internal.str[0] = '\0';