summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--icespider/embedded/clientSocket.cpp55
-rw-r--r--icespider/embedded/clientSocket.h33
-rw-r--r--icespider/embedded/embedded.cpp125
-rw-r--r--icespider/embedded/embedded.h69
-rw-r--r--icespider/embedded/listenSocket.cpp32
-rw-r--r--icespider/embedded/listenSocket.h20
-rw-r--r--icespider/embedded/socketEvents.h19
-rw-r--r--icespider/embedded/socketHandler.cpp39
-rw-r--r--icespider/embedded/socketHandler.h28
9 files changed, 234 insertions, 186 deletions
diff --git a/icespider/embedded/clientSocket.cpp b/icespider/embedded/clientSocket.cpp
new file mode 100644
index 0000000..73aa3cf
--- /dev/null
+++ b/icespider/embedded/clientSocket.cpp
@@ -0,0 +1,55 @@
+#include "clientSocket.h"
+#include <unistd.h>
+#include <string.h>
+#include <sys/socket.h>
+
+namespace IceSpider::Embedded {
+ static socklen_t clientlen = sizeof(struct sockaddr_in);
+
+ ClientSocket::ClientSocket(int pfd) :
+ SocketHandler(accept(pfd, (struct sockaddr *) &clientaddr, &clientlen)),
+ buf(BUFSIZ),
+ rec(0),
+ state(State::reading_headers)
+ {
+ }
+
+ FdSocketEventResultFuture ClientSocket::read(Listener * listener)
+ {
+ Work w([this]() {
+ if (buf.size() == rec) {
+ buf.resize(rec * 2);
+ }
+ auto r = ::read(fd, &buf.at(rec), buf.size() - rec);
+ if (r < 1) {
+ return FDSetChange::Remove;
+ }
+ switch (state) {
+ case State::reading_headers:
+ read_headers(r);
+ break;
+ case State::streaming_input:
+ stream_input(r);
+ break;
+ }
+ return FDSetChange::NoChange;
+ });
+ return returnQueued(listener, fd, std::move(w));
+ }
+
+ void ClientSocket::read_headers(int r)
+ {
+ buf[rec + r] = 0;
+ if (strstr(&buf.at(rec > 3 ? rec - 2 : 0), "\r\n")) {
+ auto w = ::write(fd, "HTTP/1.1 204 No content\r\n\r\n", 27);
+ (void)w;
+ rec = 0;
+ }
+ rec += r;
+ }
+
+ void ClientSocket::stream_input(int)
+ {
+ }
+}
+
diff --git a/icespider/embedded/clientSocket.h b/icespider/embedded/clientSocket.h
new file mode 100644
index 0000000..0d6d526
--- /dev/null
+++ b/icespider/embedded/clientSocket.h
@@ -0,0 +1,33 @@
+#ifndef ICESPIDER_EMBEDDED_CLIENTSOCKET_H
+#define ICESPIDER_EMBEDDED_CLIENTSOCKET_H
+
+#include "socketHandler.h"
+#include <vector>
+#include <netinet/in.h>
+
+namespace IceSpider::Embedded {
+ class ClientSocket : public SocketHandler {
+ public:
+ ClientSocket(int fd);
+
+ FdSocketEventResultFuture read(Listener * listener) override;
+
+ private:
+ inline void read_headers(int bytes);
+ inline void stream_input(int bytes);
+
+ enum class State {
+ reading_headers,
+ streaming_input,
+ };
+
+ struct sockaddr_in clientaddr;
+ std::vector<char> buf;
+ std::size_t rec;
+ State state;
+ };
+
+}
+
+#endif
+
diff --git a/icespider/embedded/embedded.cpp b/icespider/embedded/embedded.cpp
index 9b65839..2b1cfcd 100644
--- a/icespider/embedded/embedded.cpp
+++ b/icespider/embedded/embedded.cpp
@@ -1,123 +1,7 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
#include "embedded.h"
-#include <lockHelpers.h>
-#include <functional>
-#include <future>
-#include <boost/assert.hpp>
-
-static socklen_t clientlen = sizeof(struct sockaddr_in);
+#include "listenSocket.h"
namespace IceSpider::Embedded {
- SocketHandler::SocketHandler(int f) :
- fd(f)
- {
- if (fd < 0) {
- throw std::runtime_error("Invalid socket");
- }
- }
-
- SocketHandler::~SocketHandler()
- {
- close(fd);
- }
-
- FdSocketEventResultFuture SocketHandler::returnNow(int fd, const SocketEventResult && ser)
- {
- std::promise<SocketEventResult> p;
- p.set_value(ser);
- return { fd, p.get_future() };
- }
-
- FdSocketEventResultFuture SocketHandler::returnQueued(Listener * listener, int fd, Work && work)
- {
- auto f = work.get_future();
- BOOST_VERIFY_MSG(listener->work.try_enqueue(std::move(work)), "try_enqueue");
- return { fd, std::move(f) };
- }
-
- FdSocketEventResultFuture SocketHandler::except(Listener *)
- {
- return returnNow(fd, FDSetChange::Remove);
- }
-
- ClientSocket::ClientSocket(int pfd) :
- SocketHandler(accept(pfd, (struct sockaddr *) &clientaddr, &clientlen)),
- buf(BUFSIZ),
- rec(0),
- state(State::reading_headers)
- {
- }
-
- FdSocketEventResultFuture ClientSocket::read(Listener * listener)
- {
- Work w([this]() {
- if (buf.size() == rec) {
- buf.resize(rec * 2);
- }
- auto r = ::read(fd, &buf.at(rec), buf.size() - rec);
- if (r < 1) {
- return FDSetChange::Remove;
- }
- switch (state) {
- case State::reading_headers:
- read_headers(r);
- break;
- case State::streaming_input:
- stream_input(r);
- break;
- }
- return FDSetChange::NoChange;
- });
- return returnQueued(listener, fd, std::move(w));
- }
-
- void ClientSocket::read_headers(int r)
- {
- buf[rec + r] = 0;
- if (strstr(&buf.at(rec > 3 ? rec - 2 : 0), "\r\n")) {
- auto w = ::write(fd, "HTTP/1.1 204 No content\r\n\r\n", 27);
- (void)w;
- rec = 0;
- }
- rec += r;
- }
-
- void ClientSocket::stream_input(int)
- {
- }
-
- ListenSocket::ListenSocket(unsigned short portno) :
- SocketHandler(socket(AF_INET, SOCK_STREAM, 0))
- {
- int optval = 1;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int));
-
- bzero(&serveraddr, sizeof(serveraddr));
- serveraddr.sin_family = AF_INET;
- serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
- serveraddr.sin_port = htons(portno);
-
- if (bind(fd, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0) {
- throw std::runtime_error("ERROR on binding");
- }
-
- if (listen(fd, 5) < 0) {
- throw std::runtime_error("ERROR on listen");
- }
- }
-
- FdSocketEventResultFuture ListenSocket::read(Listener * listener)
- {
- return returnNow(listener->create<ClientSocket>(fd), FDSetChange::AddNew);
- }
-
Listener::Listener() :
work(1024),
topSock(0)
@@ -213,13 +97,6 @@ namespace IceSpider::Embedded {
}
}
- template<typename T, typename ... P> inline int Listener::create(const P & ... p)
- {
- auto s = std::make_unique<T>(p...);
- topSock = std::max(s->fd + 1, topSock);
- return (sockets[s->fd] = std::move(s))->fd;
- }
-
void Listener::add(int fd)
{
FD_SET(fd, &rfds);
diff --git a/icespider/embedded/embedded.h b/icespider/embedded/embedded.h
index 08f280a..7d7fafa 100644
--- a/icespider/embedded/embedded.h
+++ b/icespider/embedded/embedded.h
@@ -1,75 +1,15 @@
#ifndef ICESPIDER_EMBEDDED_H
#define ICESPIDER_EMBEDDED_H
-#include <sys/select.h>
-#include <netinet/in.h>
#include <visibility.h>
#include <memory>
#include <array>
#include <vector>
-#include <future>
#include </usr/include/semaphore.h>
#include <blockingconcurrentqueue.h>
+#include "socketHandler.h"
namespace IceSpider::Embedded {
- class Listener;
-
- enum class FDSetChange {
- NoChange,
- AddNew,
- Remove,
- };
- typedef std::tuple<FDSetChange> SocketEventResult;
- typedef std::future<SocketEventResult> SocketEventResultFuture;
- typedef std::tuple<int, SocketEventResultFuture> FdSocketEventResultFuture;
-
- class SocketHandler {
- public:
- typedef std::packaged_task<SocketEventResult()> Work;
-
- SocketHandler(int f);
- ~SocketHandler();
-
- static inline FdSocketEventResultFuture returnNow(int, const SocketEventResult &&);
- static inline FdSocketEventResultFuture returnQueued(Listener *, int, Work &&);
-
- virtual FdSocketEventResultFuture read(Listener *) = 0;
- virtual FdSocketEventResultFuture except(Listener *);
-
- const int fd;
- };
-
- class ClientSocket : public SocketHandler {
- public:
- ClientSocket(int fd);
-
- FdSocketEventResultFuture read(Listener * listener) override;
-
- private:
- inline void read_headers(int bytes);
- inline void stream_input(int bytes);
-
- enum class State {
- reading_headers,
- streaming_input,
- };
-
- struct sockaddr_in clientaddr;
- std::vector<char> buf;
- std::size_t rec;
- State state;
- };
-
- class ListenSocket : public SocketHandler {
- public:
- ListenSocket(unsigned short portno);
-
- FdSocketEventResultFuture read(Listener * listener) override;
-
- private:
- struct sockaddr_in serveraddr;
- };
-
class DLL_PUBLIC Listener {
public:
typedef moodycamel::BlockingConcurrentQueue<SocketHandler::Work> WorkQueue;
@@ -83,7 +23,12 @@ namespace IceSpider::Embedded {
void run();
- template<typename T, typename ... P> inline int create(const P & ... p);
+ template<typename T, typename ... P> inline int create(const P & ... p)
+ {
+ auto s = std::make_unique<T>(p...);
+ topSock = std::max(s->fd + 1, topSock);
+ return (sockets[s->fd] = std::move(s))->fd;
+ }
WorkQueue work;
diff --git a/icespider/embedded/listenSocket.cpp b/icespider/embedded/listenSocket.cpp
new file mode 100644
index 0000000..945ba43
--- /dev/null
+++ b/icespider/embedded/listenSocket.cpp
@@ -0,0 +1,32 @@
+#include "listenSocket.h"
+#include "embedded.h"
+#include "clientSocket.h"
+#include <string.h>
+
+namespace IceSpider::Embedded {
+ ListenSocket::ListenSocket(unsigned short portno) :
+ SocketHandler(socket(AF_INET, SOCK_STREAM, 0))
+ {
+ int optval = 1;
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int));
+
+ memset(&serveraddr, 0, sizeof(serveraddr));
+ serveraddr.sin_family = AF_INET;
+ serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ serveraddr.sin_port = htons(portno);
+
+ if (bind(fd, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0) {
+ throw std::runtime_error("ERROR on binding");
+ }
+
+ if (listen(fd, 5) < 0) {
+ throw std::runtime_error("ERROR on listen");
+ }
+ }
+
+ FdSocketEventResultFuture ListenSocket::read(Listener * listener)
+ {
+ return returnNow(listener->create<ClientSocket>(fd), FDSetChange::AddNew);
+ }
+}
+
diff --git a/icespider/embedded/listenSocket.h b/icespider/embedded/listenSocket.h
new file mode 100644
index 0000000..36a704f
--- /dev/null
+++ b/icespider/embedded/listenSocket.h
@@ -0,0 +1,20 @@
+#ifndef ICESPIDER_EMBEDDED_LISTENSOCKET_H
+#define ICESPIDER_EMBEDDED_LISTENSOCKET_H
+
+#include "socketHandler.h"
+#include <netinet/in.h>
+
+namespace IceSpider::Embedded {
+ class ListenSocket : public SocketHandler {
+ public:
+ ListenSocket(unsigned short portno);
+
+ FdSocketEventResultFuture read(Listener * listener) override;
+
+ private:
+ struct sockaddr_in serveraddr;
+ };
+}
+
+#endif
+
diff --git a/icespider/embedded/socketEvents.h b/icespider/embedded/socketEvents.h
new file mode 100644
index 0000000..9f94d04
--- /dev/null
+++ b/icespider/embedded/socketEvents.h
@@ -0,0 +1,19 @@
+#ifndef ICESPIDER_EMBEDDED_SOCKETEVENTS_H
+#define ICESPIDER_EMBEDDED_SOCKETEVENTS_H
+
+#include <tuple>
+#include <future>
+
+namespace IceSpider::Embedded {
+ enum class FDSetChange {
+ NoChange,
+ AddNew,
+ Remove,
+ };
+ typedef std::tuple<FDSetChange> SocketEventResult;
+ typedef std::future<SocketEventResult> SocketEventResultFuture;
+ typedef std::tuple<int, SocketEventResultFuture> FdSocketEventResultFuture;
+}
+
+#endif
+
diff --git a/icespider/embedded/socketHandler.cpp b/icespider/embedded/socketHandler.cpp
new file mode 100644
index 0000000..7d93afd
--- /dev/null
+++ b/icespider/embedded/socketHandler.cpp
@@ -0,0 +1,39 @@
+#include "socketHandler.h"
+#include "embedded.h"
+#include <boost/assert.hpp>
+#include <unistd.h>
+
+namespace IceSpider::Embedded {
+ SocketHandler::SocketHandler(int f) :
+ fd(f)
+ {
+ if (fd < 0) {
+ throw std::runtime_error("Invalid socket");
+ }
+ }
+
+ SocketHandler::~SocketHandler()
+ {
+ close(fd);
+ }
+
+ FdSocketEventResultFuture SocketHandler::returnNow(int fd, const SocketEventResult && ser)
+ {
+ std::promise<SocketEventResult> p;
+ p.set_value(ser);
+ return { fd, p.get_future() };
+ }
+
+ FdSocketEventResultFuture SocketHandler::returnQueued(Listener * listener, int fd, Work && work)
+ {
+ auto f = work.get_future();
+ BOOST_VERIFY_MSG(listener->work.try_enqueue(std::move(work)), "try_enqueue");
+ return { fd, std::move(f) };
+ }
+
+ FdSocketEventResultFuture SocketHandler::except(Listener *)
+ {
+ return returnNow(fd, FDSetChange::Remove);
+ }
+}
+
diff --git a/icespider/embedded/socketHandler.h b/icespider/embedded/socketHandler.h
new file mode 100644
index 0000000..67f5a36
--- /dev/null
+++ b/icespider/embedded/socketHandler.h
@@ -0,0 +1,28 @@
+#ifndef ICESPIDER_EMBEDDED_SOCKETHANDLER_H
+#define ICESPIDER_EMBEDDED_SOCKETHANDLER_H
+
+#include <future>
+#include "socketEvents.h"
+
+namespace IceSpider::Embedded {
+ class Listener;
+
+ class SocketHandler {
+ public:
+ typedef std::packaged_task<SocketEventResult()> Work;
+
+ SocketHandler(int f);
+ ~SocketHandler();
+
+ static FdSocketEventResultFuture returnNow(int, const SocketEventResult &&);
+ static FdSocketEventResultFuture returnQueued(Listener *, int, Work &&);
+
+ virtual FdSocketEventResultFuture read(Listener *) = 0;
+ virtual FdSocketEventResultFuture except(Listener *);
+
+ const int fd;
+ };
+}
+
+#endif
+