This commit is contained in:
Avi Kivity
2014-08-14 11:07:05 +03:00
parent 7ea696c29e
commit b6c91052e2
3 changed files with 22 additions and 20 deletions

View File

@@ -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<tmp_buf> header) {
parse_header(std::move(header));
});
@@ -80,22 +78,18 @@ public:
}
void parse_header(future<tmp_buf> 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<size_t> n) mutable {
write_response_headers(_response_headers.begin()).then(
[this] (future<size_t> done) {
write_body().then(
[this] (future<size_t> done) {
_write_buf.flush().then(
[this] (future<bool> done) {
delete this;
_write_buf.write("\r\n", 2).then(
[this] (future<size_t> done) mutable {
write_body().then(
[this] (future<size_t> done) {
_write_buf.flush().then(
[this] (future<bool> 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 = "<html><head><title>this is the future</title></head><body><p>Future!!</p></body></html>";
respond();

View File

@@ -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 <typename Func>
void schedule(Func&& func) {
_task = make_task(std::forward<Func>(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<CharType>;
size_t available() const { return _end - _begin; }
@@ -524,8 +529,9 @@ void input_stream_buffer<CharType>::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<CharType>::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<CharType>::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<size_t> 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);
});
}

View File

@@ -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';