blob: 939731d4fa176ed9e681a0eafae4ec21777df0ba [file] [log] [blame]
Daniel Petti1cb5e332013-10-01 05:05:15 +00001#include <string.h>
2
3#include "aos/atom_code/output/HTTPServer.h"
4#include "aos/atom_code/output/evhttp_ctemplate_emitter.h"
5#include "aos/atom_code/output/ctemplate_cache.h"
6#include "aos/common/messages/RobotState.q.h"
7#include "ctemplate/template.h"
8#include "aos/atom_code/init.h"
9#include "aos/common/logging/logging.h"
10#include "aos/atom_code/configuration.h"
11
12#include "frc971/constants.h"
13
14RegisterTemplateFilename(ROBOT_HTML, "robot.html.tpl");
15
16namespace frc971 {
17
18class CameraServer : public aos::http::HTTPServer {
19 public:
20 CameraServer() : HTTPServer(::aos::configuration::GetRootDirectory(), 8080),
21 buf_(NULL) {
22 AddPage<CameraServer>("/robot.html", &CameraServer::RobotHTML, this);
23 }
24
25 private:
26 evbuffer *buf_;
27 bool Setup(evhttp_request *request, const char *content_type) {
28 if (evhttp_add_header(evhttp_request_get_output_headers(request),
29 "Content-Type", content_type) == -1) {
30 LOG(WARNING, "adding Content-Type failed\n");
31 evhttp_send_error(request, HTTP_INTERNAL, NULL);
32 return false;
33 }
34 if (buf_ == NULL) buf_ = evbuffer_new();
35 if (buf_ == NULL) {
36 LOG(WARNING, "evbuffer_new() failed\n");
37 evhttp_send_error(request, HTTP_INTERNAL, NULL);
38 return false;
39 }
40 return true;
41 }
42 void RobotHTML(evhttp_request *request) {
43 if (!Setup(request, "text/html")) return;
44
45 ctemplate::TemplateDictionary dict(ROBOT_HTML);
46 const char *host = evhttp_find_header(
47 evhttp_request_get_input_headers(request), "Host");
48 if (host == NULL) {
49 evhttp_send_error(request, HTTP_BADREQUEST, "no Host header");
50 return;
51 }
52 const char *separator = strchrnul(host, ':');
53 size_t length = separator - host;
54 // Don't include the last ':' (or the terminating '\0') or anything else
55 // after it.
56 dict.SetValue("HOST", ctemplate::TemplateString(host, length));
57
58 if (!aos::robot_state.FetchLatest()) {
59 LOG(WARNING, "getting a RobotState message failed\n");
60 evhttp_send_error(request, HTTP_INTERNAL, NULL);
61 return;
62 }
63 int center;
64 if (!constants::camera_center(&center)) {
65 evhttp_send_error(request, HTTP_INTERNAL, NULL);
66 return;
67 }
68 dict.SetIntValue("CENTER", center);
69
70 aos::http::EvhttpCtemplateEmitter emitter(buf_);
71 if (!aos::http::get_template_cache()->
72 ExpandWithData(ROBOT_HTML, ctemplate::STRIP_WHITESPACE,
73 &dict, NULL, &emitter)) {
74 LOG(ERROR, "expanding the template failed\n");
75 evhttp_send_error(request, HTTP_INTERNAL, NULL);
76 return;
77 }
78 if (emitter.error()) {
79 evhttp_send_error(request, HTTP_INTERNAL, NULL);
80 return;
81 }
82 evhttp_send_reply(request, HTTP_OK, NULL, buf_);
83 }
84};
85
86} // namespace frc971
87
88int main() {
89 ::aos::InitNRT();
90 ::frc971::CameraServer server;
91 server.Run();
92 ::aos::Cleanup();
93}