blob: 944f417245543f839f7620fa44ea5d41c34b73fb [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001#include <string.h>
2
brians343bc112013-02-10 01:53:46 +00003#include "aos/atom_code/output/HTTPServer.h"
4#include "aos/atom_code/output/evhttp_ctemplate_emitter.h"
brians2fdfc072013-02-26 05:35:15 +00005#include "aos/atom_code/output/ctemplate_cache.h"
6#include "aos/common/Configuration.h"
7#include "aos/common/messages/RobotState.q.h"
brians343bc112013-02-10 01:53:46 +00008#include "ctemplate/template.h"
Brian Silverman598800f2013-05-09 17:08:42 -07009#include "aos/atom_code/init.h"
10#include "aos/common/logging/logging.h"
brians343bc112013-02-10 01:53:46 +000011
12#include "frc971/constants.h"
13
14RegisterTemplateFilename(ROBOT_HTML, "robot.html.tpl");
15
16namespace frc971 {
17
brians343bc112013-02-10 01:53:46 +000018class CameraServer : public aos::http::HTTPServer {
19 public:
brians2fdfc072013-02-26 05:35:15 +000020 CameraServer() : HTTPServer(aos::configuration::GetRootDirectory(), 8080),
21 buf_(NULL) {
brians343bc112013-02-10 01:53:46 +000022 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
brians2fdfc072013-02-26 05:35:15 +000058 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 }
brians343bc112013-02-10 01:53:46 +000063 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_);
brians2fdfc072013-02-26 05:35:15 +000071 if (!aos::http::get_template_cache()->
72 ExpandWithData(ROBOT_HTML, ctemplate::STRIP_WHITESPACE,
73 &dict, NULL, &emitter)) {
brians343bc112013-02-10 01:53:46 +000074 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
Brian Silverman598800f2013-05-09 17:08:42 -070088int main() {
89 ::aos::InitNRT();
90 ::frc971::CameraServer server;
91 server.Run();
92 ::aos::Cleanup();
93}