rippled
Loading...
Searching...
No Matches
JSONRPCUtil.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/basics/Log.h>
21#include <xrpl/beast/utility/Journal.h>
22#include <xrpl/json/Output.h>
23#include <xrpl/protocol/BuildInfo.h>
24#include <xrpl/protocol/SystemParameters.h>
25#include <xrpl/server/detail/JSONRPCUtil.h>
26
27#include <ctime>
28#include <string>
29
30namespace ripple {
31
34{
35 // CHECKME This is probably called often enough that optimizing it makes
36 // sense. There's no point in doing all this work if this function
37 // gets called multiple times a second.
38 char buffer[96];
39 time_t now;
40 time(&now);
41 struct tm now_gmt
42 {
43 };
44#ifndef _MSC_VER
45 gmtime_r(&now, &now_gmt);
46#else
47 gmtime_s(&now_gmt, &now);
48#endif
49 strftime(
50 buffer,
51 sizeof(buffer),
52 "Date: %a, %d %b %Y %H:%M:%S +0000\r\n",
53 &now_gmt);
54 return std::string(buffer);
55}
56
57void
59 int nStatus,
60 std::string const& content,
61 Json::Output const& output,
63{
64 JLOG(j.trace()) << "HTTP Reply " << nStatus << " " << content;
65
66 if (content.empty() && nStatus == 401)
67 {
68 output("HTTP/1.0 401 Authorization Required\r\n");
69 output(getHTTPHeaderTimestamp());
70
71 // CHECKME this returns a different version than the replies below. Is
72 // this by design or an accident or should it be using
73 // BuildInfo::getFullVersionString () as well?
74 output("Server: " + systemName() + "-json-rpc/v1");
75 output("\r\n");
76
77 // Be careful in modifying this! If you change the contents you MUST
78 // update the Content-Length header as well to indicate the correct
79 // size of the data.
80 output(
81 "WWW-Authenticate: Basic realm=\"jsonrpc\"\r\n"
82 "Content-Type: text/html\r\n"
83 "Content-Length: 296\r\n"
84 "\r\n"
85 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 "
86 "Transitional//EN\"\r\n"
87 "\"http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd"
88 "\">\r\n"
89 "<HTML>\r\n"
90 "<HEAD>\r\n"
91 "<TITLE>Error</TITLE>\r\n"
92 "<META HTTP-EQUIV='Content-Type' "
93 "CONTENT='text/html; charset=ISO-8859-1'>\r\n"
94 "</HEAD>\r\n"
95 "<BODY><H1>401 Unauthorized.</H1></BODY>\r\n");
96
97 return;
98 }
99
100 switch (nStatus)
101 {
102 case 200:
103 output("HTTP/1.1 200 OK\r\n");
104 break;
105 case 202:
106 output("HTTP/1.1 202 Accepted\r\n");
107 break;
108 case 400:
109 output("HTTP/1.1 400 Bad Request\r\n");
110 break;
111 case 401:
112 output("HTTP/1.1 401 Authorization Required\r\n");
113 break;
114 case 403:
115 output("HTTP/1.1 403 Forbidden\r\n");
116 break;
117 case 404:
118 output("HTTP/1.1 404 Not Found\r\n");
119 break;
120 case 405:
121 output("HTTP/1.1 405 Method Not Allowed\r\n");
122 break;
123 case 429:
124 output("HTTP/1.1 429 Too Many Requests\r\n");
125 break;
126 case 500:
127 output("HTTP/1.1 500 Internal Server Error\r\n");
128 break;
129 case 501:
130 output("HTTP/1.1 501 Not Implemented\r\n");
131 break;
132 case 503:
133 output("HTTP/1.1 503 Server is overloaded\r\n");
134 break;
135 }
136
137 output(getHTTPHeaderTimestamp());
138
139 output(
140 "Connection: Keep-Alive\r\n"
141 "Content-Length: ");
142
143 // VFALCO TODO Determine if/when this header should be added
144 // if (context.app.config().RPC_ALLOW_REMOTE)
145 // output ("Access-Control-Allow-Origin: *\r\n");
146
147 output(std::to_string(content.size() + 2));
148 output(
149 "\r\n"
150 "Content-Type: application/json; charset=UTF-8\r\n");
151
152 output("Server: " + systemName() + "-json-rpc/");
154 output(
155 "\r\n"
156 "\r\n");
157 output(content);
158 output("\r\n");
159}
160
161} // namespace ripple
A generic endpoint for log messages.
Definition Journal.h:60
Stream trace() const
Severity stream access functions.
Definition Journal.h:322
T empty(T... args)
std::string const & getFullVersionString()
Full server version string.
Definition BuildInfo.cpp:81
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
void HTTPReply(int nStatus, std::string const &strMsg, Json::Output const &, beast::Journal j)
static std::string const & systemName()
std::string getHTTPHeaderTimestamp()
T size(T... args)
T to_string(T... args)