![]() |
RTBKit
0.9
Open-source framework to create real-time ad bidding systems.
|
00001 /* http_adserver_connector.cc -*- C++ -*- 00002 Wolfgang Sourdeau, April 2013 00003 Copyright (c) 2013 Datacratic. All rights reserved. 00004 */ 00005 00006 00007 #include <memory> 00008 00009 #include "http_adserver_connector.h" 00010 00011 00012 using namespace std; 00013 using namespace RTBKIT; 00014 00015 00016 /****************************************************************************/ 00017 /* HTTPADSERVERCONNECTIONHANDLER */ 00018 /****************************************************************************/ 00019 00020 HttpAdServerConnectionHandler:: 00021 HttpAdServerConnectionHandler(HttpAdServerHttpEndpoint & endpoint, 00022 const HttpAdServerRequestCb & requestCb) 00023 : endpoint_(endpoint), requestCb_(requestCb) 00024 { 00025 } 00026 00027 void 00028 HttpAdServerConnectionHandler:: 00029 handleJson(const HttpHeader & header, const Json::Value & json, 00030 const string & jsonStr) 00031 { 00032 string resultMsg; 00033 00034 transport().assertLockedByThisThread(); 00035 00036 auto onSendFinished = [&] () { 00037 Date endRq = Date::now(); 00038 double timeElapsedMs = endRq.secondsSince(this->firstData) * 1000; 00039 endpoint_.doEvent("rqTimeMs", ET_OUTCOME, timeElapsedMs); 00040 00041 this->transport().associateWhenHandlerFinished 00042 (endpoint_.makeNewHandler(), "rqFinished"); 00043 }; 00044 00045 try { 00046 requestCb_(header, json, jsonStr); 00047 resultMsg = ("HTTP/1.1 200 OK\r\n" 00048 "Content-Type: none\r\n" 00049 "Content-Length: 0\r\n" 00050 "\r\n"); 00051 } 00052 catch (const exception & exc) { 00053 cerr << "error parsing adserver request " << json << ": " 00054 << exc.what() << endl; 00055 endpoint_.doEvent("error.rqParsingError"); 00056 00057 Json::Value responseJson; 00058 responseJson["error"] = "error parsing AdServer message"; 00059 responseJson["message"] = json; 00060 responseJson["details"] = exc.what(); 00061 00062 string response = responseJson.toString(); 00063 resultMsg = ML::format("HTTP/1.1 400 Bad Request\r\n" 00064 "Content-Type: text/json\r\n" 00065 "Content-Length: %zd\r\n" 00066 "\r\n%s", 00067 response.size(), response.c_str()); 00068 } 00069 00070 send(resultMsg, 00071 NEXT_CONTINUE, 00072 onSendFinished); 00073 } 00074 00075 00076 /****************************************************************************/ 00077 /* HTTPADSERVERHTTPENDPOINT */ 00078 /****************************************************************************/ 00079 00080 HttpAdServerHttpEndpoint:: 00081 HttpAdServerHttpEndpoint(int port, const HttpAdServerRequestCb & requestCb) 00082 : HttpEndpoint("adserver-ep-" + to_string(port)), 00083 port_(port), requestCb_(requestCb) 00084 { 00085 } 00086 00087 HttpAdServerHttpEndpoint:: 00088 HttpAdServerHttpEndpoint(HttpAdServerHttpEndpoint && otherEndpoint) 00089 : HttpEndpoint("adserver-ep-" + to_string(otherEndpoint.port_)) 00090 { 00091 port_ = otherEndpoint.port_; 00092 requestCb_ = otherEndpoint.requestCb_; 00093 } 00094 00095 HttpAdServerHttpEndpoint:: 00096 ~HttpAdServerHttpEndpoint() 00097 { 00098 shutdown(); 00099 } 00100 00101 HttpAdServerHttpEndpoint & 00102 HttpAdServerHttpEndpoint:: 00103 operator = (const HttpAdServerHttpEndpoint& other) 00104 { 00105 if (this != &other) { 00106 port_ = other.port_; 00107 requestCb_ = other.requestCb_; 00108 } 00109 00110 return *this; 00111 } 00112 00113 int 00114 HttpAdServerHttpEndpoint:: 00115 getPort() 00116 const 00117 { 00118 return port_; 00119 } 00120 00121 shared_ptr<ConnectionHandler> 00122 HttpAdServerHttpEndpoint:: 00123 makeNewHandler() 00124 { 00125 return std::make_shared<HttpAdServerConnectionHandler>(*this, requestCb_); 00126 } 00127 00128 00129 /****************************************************************************/ 00130 /* HTTPADSERVERCONNECTOR */ 00131 /****************************************************************************/ 00132 00133 HttpAdServerConnector:: 00134 HttpAdServerConnector(const string & serviceName, 00135 const shared_ptr<Datacratic::ServiceProxies> & proxy) 00136 : AdServerConnector(serviceName, proxy) 00137 { 00138 } 00139 00140 void 00141 HttpAdServerConnector:: 00142 registerEndpoint(int port, const HttpAdServerRequestCb & requestCb) 00143 { 00144 endpoints_.emplace_back(port, requestCb); 00145 } 00146 00147 void 00148 HttpAdServerConnector:: 00149 init(const shared_ptr<ConfigurationService> & config) 00150 { 00151 AdServerConnector::init(config); 00152 for (HttpAdServerHttpEndpoint & endpoint: endpoints_) { 00153 auto onEvent = bind(&ServiceBase::recordEvent, this, 00154 placeholders::_1, placeholders::_2, 00155 placeholders::_3); 00156 endpoint.onEvent = onEvent; 00157 } 00158 } 00159 00160 void 00161 HttpAdServerConnector:: 00162 shutdown() 00163 { 00164 for (HttpAdServerHttpEndpoint & endpoint: endpoints_) { 00165 endpoint.shutdown(); 00166 } 00167 AdServerConnector::shutdown(); 00168 } 00169 00170 void 00171 HttpAdServerConnector:: 00172 bindTcp() 00173 { 00174 for (HttpAdServerHttpEndpoint & endpoint: endpoints_) { 00175 endpoint.init(endpoint.getPort(), "0.0.0.0", 4); 00176 } 00177 } 00178 00179 void 00180 HttpAdServerConnector:: 00181 start() 00182 { 00183 for (HttpAdServerHttpEndpoint & endpoint: endpoints_) { 00184 endpoint.makeRealTime(10); 00185 } 00186 AdServerConnector::start(); 00187 }