File: x_json_handler.cc

package info (click to toggle)
golang-github-google-certificate-transparency 0.0~git20160709.0.0f6e3d1~ds1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 5,676 kB
  • sloc: cpp: 35,278; python: 11,838; java: 1,911; sh: 1,885; makefile: 950; xml: 520; ansic: 225
file content (102 lines) | stat: -rw-r--r-- 2,914 bytes parent folder | download
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
#include "server/x_json_handler.h"

#include <functional>

#include "log/frontend.h"
#include "server/json_output.h"
#include "util/statusor.h"
#include "util/thread_pool.h"

namespace cert_trans {

using ct::LogEntry;
using ct::SignedCertificateTimestamp;
using ct::X_JSON_ENTRY;
using std::bind;
using std::make_shared;
using std::move;
using std::multimap;
using std::placeholders::_1;
using std::shared_ptr;
using std::string;
using util::Status;


namespace {


shared_ptr<JsonObject> ExtractJson(libevent::Base* base, evhttp_request* req) {
  CHECK_NOTNULL(base);
  CHECK_NOTNULL(req);
  if (evhttp_request_get_command(req) != EVHTTP_REQ_POST) {
    SendJsonError(base, req, HTTP_BADMETHOD, "Method not allowed.");
    return nullptr;
  }

  // TODO(pphaneuf): Should we check that Content-Type says
  // "application/json", as recommended by RFC4627?
  shared_ptr<JsonObject> json_body(
      make_shared<JsonObject>(evhttp_request_get_input_buffer(req)));
  if (!json_body->Ok() || !json_body->IsType(json_type_object)) {
    SendJsonError(base, req, HTTP_BADREQUEST,
                  "Unable to parse provided JSON.");
    return nullptr;
  }

  VLOG(2) << "ExtractJson:\n" << json_body->DebugString();
  return json_body;
}


}  // namespace


XJsonHttpHandler::XJsonHttpHandler(LogLookup* log_lookup,
                                   const ReadOnlyDatabase* db,
                                   const ClusterStateController* controller,
                                   Frontend* frontend, ThreadPool* pool,
                                   libevent::Base* event_base,
                                   StalenessTracker* staleness_tracker)
    : HttpHandler(log_lookup, db, controller, pool, event_base,
                  staleness_tracker),
      frontend_(frontend) {
}


void XJsonHttpHandler::AddHandlers(libevent::HttpServer* server) {
  if (frontend_) {
    // Proxy the add-* calls too, technically we could serve them, but a
    // more up-to-date node will have a better chance of handling dupes
    // correctly, rather than bloating the tree.
    AddProxyWrappedHandler(server, "/ct/v1/add-json",
                           bind(&XJsonHttpHandler::AddJson, this, _1));
  }
}


void XJsonHttpHandler::AddJson(evhttp_request* req) {
  shared_ptr<JsonObject> json(ExtractJson(event_base_, req));
  if (!json) {
    return;
  }

  pool_->Add(bind(&XJsonHttpHandler::BlockingAddJson, this, req, json));
}


void XJsonHttpHandler::BlockingAddJson(evhttp_request* req,
                                       shared_ptr<JsonObject> json) const {
  SignedCertificateTimestamp sct;

  LogEntry entry;
  // do this here for now
  entry.set_type(X_JSON_ENTRY);
  entry.mutable_x_json_entry()->set_json(json->ToString());

  AddEntryReply(req, CHECK_NOTNULL(frontend_)
                         ->QueueProcessedEntry(Status::OK, entry, &sct),
                sct);
}


}  // namespace cert_trans