forked from includeos/IncludeOS
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathservice.cpp
More file actions
120 lines (104 loc) · 3.91 KB
/
Copy pathservice.cpp
File metadata and controls
120 lines (104 loc) · 3.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <cmath> // rand()
#include <sstream>
#include <os>
#include <net/inet>
#include <timers>
#include <net/http/request.hpp>
#include <net/http/response.hpp>
using namespace std::chrono;
static std::string HTML_RESPONSE()
{
const int color = rand();
// Generate some HTML
std::stringstream stream;
stream << "<!DOCTYPE html><html><head>"
<< "<link href='https://fonts.googleapis.com/css?family=Ubuntu:500,300'"
<< " rel='stylesheet' type='text/css'>"
<< "<title>IncludeOS Demo Service</title></head><body>"
<< "<h1 style='color: #" << std::hex << ((color >> 8) | 0x020202)
<< "; font-family: \"Arial\", sans-serif'>"
<< "Include<span style='font-weight: lighter'>OS</span></h1>"
<< "<h2>The C++ Unikernel</h2>"
<< "<p>You have successfully booted an IncludeOS TCP service with simple http. "
<< "For a more sophisticated example, take a look at "
<< "<a href='https://github.com/hioa-cs/IncludeOS/tree/master/examples/acorn'>Acorn</a>.</p>"
<< "<footer><hr/>© 2017 IncludeOS </footer></body></html>";
return stream.str();
}
static http::Response handle_request(const http::Request& req)
{
http::Response res;
auto& header = res.header();
header.set_field(http::header::Server, "IncludeOS/0.12");
// GET /
if(req.method() == http::GET && req.uri().to_string() == "/")
{
// add HTML response
res.add_body(HTML_RESPONSE());
// set Content type and length
header.set_field(http::header::Content_Type, "text/html; charset=UTF-8");
header.set_field(http::header::Content_Length, std::to_string(res.body().size()));
}
else
{
// Generate 404 response
res.set_status_code(http::Not_Found);
}
header.set_field(http::header::Connection, "close");
return res;
}
void Service::start()
{
extern void create_network_device(int N, const char* route, const char* ip);
create_network_device(0, "10.0.0.0/24", "10.0.0.1");
// Get the first IP stack configured from config.json
auto& inet = net::Super_stack::get(0);
inet.network_config({10,0,0,42}, {255,255,255,0}, {10,0,0,1});
// Print some useful netstats every 30 secs
Timers::periodic(5s, 30s,
[&inet] (uint32_t) {
printf("<Service> TCP STATUS:\n%s\n", inet.tcp().status().c_str());
});
// Set up a TCP server on port 80
auto& server = inet.tcp().listen(80);
// Add a TCP connection handler - here a hardcoded HTTP-service
server.on_connect(
[] (net::tcp::Connection_ptr conn) {
printf("<Service> @on_connect: Connection %s successfully established.\n",
conn->remote().to_string().c_str());
// read async with a buffer size of 1024 bytes
// define what to do when data is read
conn->on_read(1024,
[conn] (auto buf)
{
try {
const std::string data((const char*) buf->data(), buf->size());
// try to parse the request
http::Request req{data};
// handle the request, getting a matching response
conn->write(handle_request(req));
}
catch(const std::exception& e)
{
printf("<Service> Unable to parse request:\n%s\n", e.what());
}
});
});
printf("*** Linux userspace library demo started ***\n");
}