Commit c7169630 authored by Mathieu Stefani's avatar Mathieu Stefani

The parser is now associated to a particular connection (peer) so that it can...

The parser is now associated to a particular connection (peer) so that it can parse a request from multiple tcp packets
parent 9ee9db90
...@@ -18,6 +18,7 @@ class MyHandler : public Net::Http::Handler { ...@@ -18,6 +18,7 @@ class MyHandler : public Net::Http::Handler {
response.headers response.headers
.add(std::make_shared<Server>("lys")) .add(std::make_shared<Server>("lys"))
.add(std::make_shared<ContentType>(MIME(Text, Plain))); .add(std::make_shared<ContentType>(MIME(Text, Plain)));
response.writeTo(peer); response.writeTo(peer);
} }
......
...@@ -148,7 +148,6 @@ namespace Private { ...@@ -148,7 +148,6 @@ namespace Private {
if (n == Cursor::Eof) return State::Again; if (n == Cursor::Eof) return State::Again;
else if (n != ' ') raise("Malformed HTTP Request"); else if (n != ' ') raise("Malformed HTTP Request");
if (!cursor.advance(2)) return State::Again; if (!cursor.advance(2)) return State::Again;
size_t start = cursor; size_t start = cursor;
...@@ -203,11 +202,13 @@ namespace Private { ...@@ -203,11 +202,13 @@ namespace Private {
while (cursor.current() != ':') while (cursor.current() != ':')
if (!cursor.advance(1)) return State::Again; if (!cursor.advance(1)) return State::Again;
// Skip the ':'
if (!cursor.advance(1)) return State::Again; if (!cursor.advance(1)) return State::Again;
std::string name = std::string(cursor.offset(start), cursor.diff(start) - 1); std::string name = std::string(cursor.offset(start), cursor.diff(start) - 1);
// Skip the ':' // Ignore spaces
while (cursor.current() == ' ')
if (!cursor.advance(1)) return State::Again; if (!cursor.advance(1)) return State::Again;
// Read the header value // Read the header value
...@@ -309,6 +310,7 @@ namespace Private { ...@@ -309,6 +310,7 @@ namespace Private {
memcpy(buffer.data + buffer.len, data, len); memcpy(buffer.data + buffer.len, data, len);
buffer.len += len; buffer.len += len;
return true; return true;
} }
...@@ -434,6 +436,8 @@ Response::writeTo(Tcp::Peer& peer) ...@@ -434,6 +436,8 @@ Response::writeTo(Tcp::Peer& peer)
void void
Handler::onInput(const char* buffer, size_t len, Tcp::Peer& peer) { Handler::onInput(const char* buffer, size_t len, Tcp::Peer& peer) {
auto& parser = getParser(peer);
if (!parser.feed(buffer, len)) { if (!parser.feed(buffer, len)) {
cout << "Could not feed parser bro" << endl; cout << "Could not feed parser bro" << endl;
} }
...@@ -454,6 +458,21 @@ void ...@@ -454,6 +458,21 @@ void
Handler::onOutput() { Handler::onOutput() {
} }
void
Handler::onConnection(Tcp::Peer& peer) {
peer.setData(std::make_shared<Private::Parser>());
}
void
Handler::onDisconnection(Tcp::Peer& peer) {
}
Private::Parser&
Handler::getParser(Tcp::Peer& peer) {
auto data = peer.data();
return *std::static_pointer_cast<Private::Parser>(data);
}
Endpoint::Endpoint() Endpoint::Endpoint()
{ } { }
......
...@@ -259,6 +259,9 @@ namespace Private { ...@@ -259,6 +259,9 @@ namespace Private {
feed(data, len); feed(data, len);
} }
Parser(const Parser& other) = delete;
Parser(Parser&& other) = default;
bool feed(const char* data, size_t len); bool feed(const char* data, size_t len);
void reset(); void reset();
...@@ -272,7 +275,7 @@ namespace Private { ...@@ -272,7 +275,7 @@ namespace Private {
private: private:
static constexpr size_t StepsCount = 3; static constexpr size_t StepsCount = 3;
std::unique_ptr<Step> allSteps[StepsCount]; std::array<std::unique_ptr<Step>, StepsCount> allSteps;
size_t currentStep; size_t currentStep;
ssize_t contentLength; ssize_t contentLength;
...@@ -326,10 +329,14 @@ public: ...@@ -326,10 +329,14 @@ public:
void onInput(const char* buffer, size_t len, Tcp::Peer& peer); void onInput(const char* buffer, size_t len, Tcp::Peer& peer);
void onOutput(); void onOutput();
void onConnection(Tcp::Peer& peer);
void onDisconnection(Tcp::Peer& peer);
virtual void onRequest(const Request& request, Tcp::Peer& peer) = 0; virtual void onRequest(const Request& request, Tcp::Peer& peer) = 0;
private: private:
Private::Parser parser; Private::Parser& getParser(Tcp::Peer& peer);
}; };
class Endpoint { class Endpoint {
......
...@@ -139,7 +139,7 @@ IoWorker::handleIncoming(const std::shared_ptr<Peer>& peer) { ...@@ -139,7 +139,7 @@ IoWorker::handleIncoming(const std::shared_ptr<Peer>& peer) {
} }
} else { } else {
if (errno == ECONNRESET) { if (errno == ECONNRESET) {
handler_->onDisconnection(peer); handler_->onDisconnection(*peer);
close(fd); close(fd);
} }
else { else {
...@@ -149,7 +149,7 @@ IoWorker::handleIncoming(const std::shared_ptr<Peer>& peer) { ...@@ -149,7 +149,7 @@ IoWorker::handleIncoming(const std::shared_ptr<Peer>& peer) {
break; break;
} }
else if (bytes == 0) { else if (bytes == 0) {
handler_->onDisconnection(peer); handler_->onDisconnection(*peer);
close(fd); close(fd);
break; break;
} }
...@@ -174,7 +174,7 @@ IoWorker::handleNewPeer(const std::shared_ptr<Peer>& peer) ...@@ -174,7 +174,7 @@ IoWorker::handleNewPeer(const std::shared_ptr<Peer>& peer)
peers.insert(std::make_pair(fd, peer)); peers.insert(std::make_pair(fd, peer));
} }
handler_->onConnection(peer); handler_->onConnection(*peer);
poller.addFd(fd, NotifyOn::Read, Polling::Tag(fd), Polling::Mode::Edge); poller.addFd(fd, NotifyOn::Read, Polling::Tag(fd), Polling::Mode::Edge);
} }
...@@ -226,11 +226,11 @@ Handler::~Handler() ...@@ -226,11 +226,11 @@ Handler::~Handler()
{ } { }
void void
Handler::onConnection(const std::shared_ptr<Peer>& peer) { Handler::onConnection(Tcp::Peer& peer) {
} }
void void
Handler::onDisconnection(const std::shared_ptr<Peer>& peer) { Handler::onDisconnection(Tcp::Peer& peer) {
} }
Listener::Listener() Listener::Listener()
......
...@@ -105,8 +105,8 @@ public: ...@@ -105,8 +105,8 @@ public:
virtual void onInput(const char *buffer, size_t len, Tcp::Peer& peer) = 0; virtual void onInput(const char *buffer, size_t len, Tcp::Peer& peer) = 0;
virtual void onOutput() = 0; virtual void onOutput() = 0;
virtual void onConnection(const std::shared_ptr<Peer>& peer); virtual void onConnection(Tcp::Peer& peer);
virtual void onDisconnection(const std::shared_ptr<Peer>& peer); virtual void onDisconnection(Tcp::Peer& peer);
}; };
......
...@@ -15,11 +15,13 @@ using namespace std; ...@@ -15,11 +15,13 @@ using namespace std;
Peer::Peer() Peer::Peer()
: fd_(-1) : fd_(-1)
, data_(nullptr)
{ } { }
Peer::Peer(const Address& addr) Peer::Peer(const Address& addr)
: addr(addr) : addr(addr)
, fd_(-1) , fd_(-1)
, data_(nullptr)
{ } { }
Address Address
...@@ -46,6 +48,16 @@ Peer::fd() const { ...@@ -46,6 +48,16 @@ Peer::fd() const {
return fd_; return fd_;
} }
void
Peer::setData(std::shared_ptr<void> data) {
data_ = std::move(data);
}
std::shared_ptr<void>
Peer::data() const {
return data_;
}
std::ostream& operator<<(std::ostream& os, const Peer& peer) { std::ostream& operator<<(std::ostream& os, const Peer& peer) {
const auto& addr = peer.address(); const auto& addr = peer.address();
os << "(" << addr.host() << ", " << addr.port() << ") [" << peer.hostname() << "]"; os << "(" << addr.host() << ", " << addr.port() << ") [" << peer.hostname() << "]";
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "os.h" #include "os.h"
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <memory>
namespace Net { namespace Net {
...@@ -26,10 +27,15 @@ public: ...@@ -26,10 +27,15 @@ public:
void associateFd(Fd fd); void associateFd(Fd fd);
Fd fd() const; Fd fd() const;
std::shared_ptr<void> data() const;
void setData(std::shared_ptr<void> data);
private: private:
Address addr; Address addr;
std::string hostname_; std::string hostname_;
Fd fd_; Fd fd_;
std::shared_ptr<void> data_;
}; };
std::ostream& operator<<(std::ostream& os, const Peer& peer); std::ostream& operator<<(std::ostream& os, const Peer& peer);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment