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