12 #include <boost/algorithm/string.hpp>
13 #include <boost/asio.hpp>
14 #include <boost/asio/ssl.hpp>
15 #include <boost/bind.hpp>
16 #include <boost/filesystem.hpp>
17 #include <boost/foreach.hpp>
18 #include <boost/iostreams/concepts.hpp>
19 #include <boost/iostreams/stream.hpp>
20 #include <boost/shared_ptr.hpp>
21 #include "json/json_spirit_writer_template.h"
24 using namespace boost;
35 string HTTPPost(
const string& strMsg,
const map<string,string>& mapRequestHeaders)
38 s <<
"POST / HTTP/1.1\r\n"
40 <<
"Host: 127.0.0.1\r\n"
41 <<
"Content-Type: application/json\r\n"
42 <<
"Content-Length: " << strMsg.size() <<
"\r\n"
43 <<
"Connection: close\r\n"
44 <<
"Accept: application/json\r\n";
45 BOOST_FOREACH(
const PAIRTYPE(
string,
string)& item, mapRequestHeaders)
46 s << item.first <<
": " << item.second <<
"\r\n";
47 s <<
"\r\n" << strMsg;
57 string HTTPReply(
int nStatus,
const string& strMsg,
bool keepalive)
60 return strprintf(
"HTTP/1.0 401 Authorization Required\r\n"
62 "Server: bitcoin-json-rpc/%s\r\n"
63 "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n"
64 "Content-Type: text/html\r\n"
65 "Content-Length: 296\r\n"
67 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n"
68 "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd\">\r\n"
71 "<TITLE>Error</TITLE>\r\n"
72 "<META HTTP-EQUIV='Content-Type' CONTENT='text/html; charset=ISO-8859-1'>\r\n"
74 "<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
77 if (nStatus ==
HTTP_OK) cStatus =
"OK";
87 "Content-Length: %u\r\n"
88 "Content-Type: application/json\r\n"
89 "Server: bitcoin-json-rpc/%s\r\n"
95 keepalive ?
"keep-alive" :
"close",
102 string& http_method,
string& http_uri)
105 getline(stream, str);
108 vector<string> vWords;
109 boost::split(vWords, str, boost::is_any_of(
" "));
110 if (vWords.size() < 2)
114 http_method = vWords[0];
115 if (http_method !=
"GET" && http_method !=
"POST")
119 http_uri = vWords[1];
120 if (http_uri.size() == 0 || http_uri[0] !=
'/')
124 string strProto =
"";
125 if (vWords.size() > 2)
126 strProto = vWords[2];
129 const char *ver = strstr(strProto.c_str(),
"HTTP/1.");
139 getline(stream, str);
140 vector<string> vWords;
141 boost::split(vWords, str, boost::is_any_of(
" "));
142 if (vWords.size() < 2)
145 const char *ver = strstr(str.c_str(),
"HTTP/1.");
148 return atoi(vWords[1].c_str());
151 int ReadHTTPHeaders(std::basic_istream<char>& stream, map<string, string>& mapHeadersRet)
157 std::getline(stream, str);
158 if (str.empty() || str ==
"\r")
160 string::size_type nColon = str.find(
":");
161 if (nColon != string::npos)
163 string strHeader = str.substr(0, nColon);
164 boost::trim(strHeader);
165 boost::to_lower(strHeader);
166 string strValue = str.substr(nColon+1);
167 boost::trim(strValue);
168 mapHeadersRet[strHeader] = strValue;
169 if (strHeader ==
"content-length")
170 nLen =
atoi(strValue.c_str());
178 string>& mapHeadersRet,
string& strMessageRet,
181 mapHeadersRet.clear();
186 if (nLen < 0 || nLen > (
int)
MAX_SIZE)
192 vector<char> vch(nLen);
193 stream.read(&vch[0], nLen);
194 strMessageRet = string(vch.begin(), vch.end());
197 string sConHdr = mapHeadersRet[
"connection"];
199 if ((sConHdr !=
"close") && (sConHdr !=
"keep-alive"))
202 mapHeadersRet[
"connection"] =
"keep-alive";
204 mapHeadersRet[
"connection"] =
"close";
220 string JSONRPCRequest(
const string& strMethod,
const Array& params,
const Value&
id)
223 request.push_back(Pair(
"method", strMethod));
224 request.push_back(Pair(
"params", params));
225 request.push_back(Pair(
"id",
id));
226 return write_string(Value(request),
false) +
"\n";
232 if (error.type() != null_type)
233 reply.push_back(Pair(
"result", Value::null));
235 reply.push_back(Pair(
"result", result));
236 reply.push_back(Pair(
"error", error));
237 reply.push_back(Pair(
"id",
id));
244 return write_string(Value(reply),
false) +
"\n";
250 error.push_back(Pair(
"code", code));
251 error.push_back(Pair(
"message", message));
int ReadHTTPStatus(std::basic_istream< char > &stream, int &proto)
string JSONRPCReply(const Value &result, const Value &error, const Value &id)
bool ReadHTTPRequestLine(std::basic_istream< char > &stream, int &proto, string &http_method, string &http_uri)
Object JSONRPCError(int code, const string &message)
std::string DateTimeStrFormat(const char *pszFormat, int64_t nTime)
int ReadHTTPMessage(std::basic_istream< char > &stream, map< string, string > &mapHeadersRet, string &strMessageRet, int nProto)
static bool error(const char *format)
string HTTPReply(int nStatus, const string &strMsg, bool keepalive)
static string rfc1123Time()
Object JSONRPCReplyObj(const Value &result, const Value &error, const Value &id)
static const unsigned int MAX_SIZE
string FormatFullVersion()
string HTTPPost(const string &strMsg, const map< string, string > &mapRequestHeaders)
int ReadHTTPHeaders(std::basic_istream< char > &stream, map< string, string > &mapHeadersRet)
string JSONRPCRequest(const string &strMethod, const Array ¶ms, const Value &id)
int atoi(const std::string &str)