@@ -30,14 +30,18 @@ using namespace std::placeholders;
3030using namespace network ::http;
3131using namespace system ;
3232
33- const auto binary = mime_type::application_octet_stream;
33+ const auto data = mime_type::application_octet_stream;
3434const auto json = mime_type::application_json;
3535const auto text = mime_type::text_plain;
3636
3737BC_PUSH_WARNING (NO_THROW_IN_NOEXCEPT)
3838
3939// Handle get method.
4040// ----------------------------------------------------------------------------
41+ // TODO: performance timing header.
42+ // TODO: formatted error responses.
43+ // TODO: priority sort and dispatch.
44+ // TODO: URI path parse (see API doc).
4145
4246void protocol_explore::handle_receive_get (const code& ec,
4347 const method::get& request) NOEXCEPT
@@ -75,67 +79,131 @@ void protocol_explore::handle_receive_get(const code& ec,
7579 return ;
7680 }
7781
78- // /////////////////////////////////////////////////////////////////////////
79- // TODO: formatted error responses.
80- // TODO: priority sort and dispatch.
81- // TODO: URI path parse (see API doc).
82- // TODO: performance timing header.
83- // /////////////////////////////////////////////////////////////////////////
82+ if (const auto parts = split (uri.path (), " /" );
83+ !parts.empty () && parts.size () != two)
84+ {
85+ send_bad_target (*request);
86+ return ;
87+ }
88+ else
89+ {
90+ const auto hd = parts.front () == " header" || parts.front () == " hd" ;
91+ const auto bk = parts.front () == " block" || parts.front () == " bk" ;
92+ const auto tx = parts.front () == " transaction" || parts.front () == " tx" ;
93+ if (!hd && !bk && !tx)
94+ {
95+ send_bad_target (*request);
96+ return ;
97+ }
98+
99+ auto params = uri.decode_query ();
100+ const auto format = params[" format" ];
101+ const auto accepts = to_mime_types ((*request)[field::accept]);
102+ const auto is_json = contains (accepts, json) || format == " json" ;
103+ const auto is_text = contains (accepts, text) || format == " text" ;
104+ const auto is_data = contains (accepts, data) || format == " data" ;
105+ const auto wit = params[" witness" ] != " false" ;
106+ const auto hex = parts.back ();
84107
85- const auto get_tx = [&](const auto & path) NOEXCEPT
86- {
87108 hash_digest hash{};
88- if (!decode_hash (hash, path ))
109+ if ((is_json || is_text || is_data) && !decode_hash (hash, hex ))
89110 {
90111 send_bad_target (*request);
91- return chain::transaction::cptr{} ;
112+ return ;
92113 }
93114
94115 const auto & query = archive ();
95- return query.get_transaction (query.to_tx (hash), true );
96- };
97116
98- auto params = uri.decode_query ();
99- const auto hex = trim_copy (uri.path (), { " /" });
100- const auto accepts = to_mime_types ((*request)[field::accept]);
101-
102- if (contains (accepts, json) || params[" format" ] == " json" )
103- {
104- const auto tx = get_tx (hex);
105- if (!tx)
117+ if (is_json)
106118 {
119+ if (hd)
120+ {
121+ if (const auto ptr = query.get_header (query.to_header (hash)))
122+ {
123+ send_json (*request, value_from (*ptr));
124+ return ;
125+ }
126+ }
127+ else if (bk)
128+ {
129+ if (const auto ptr = query.get_block (query.to_header (hash), wit))
130+ {
131+ send_json (*request, value_from (*ptr));
132+ return ;
133+ }
134+ }
135+ else
136+ {
137+ if (const auto ptr = query.get_transaction (query.to_tx (hash), wit))
138+ {
139+ send_json (*request, value_from (*ptr));
140+ return ;
141+ }
142+ }
143+
107144 send_not_found (*request);
108145 return ;
109146 }
110-
111- send_json (*request, value_from (*tx));
112- return ;
113- }
114-
115- if (contains (accepts, binary) || params[" format" ] == " binary" )
116- {
117- const auto tx = get_tx (hex);
118- if (!tx)
147+ else if (is_text)
119148 {
149+ if (hd)
150+ {
151+ if (const auto ptr = query.get_header (query.to_header (hash)))
152+ {
153+ send_text (*request, encode_base16 (ptr->to_data ()));
154+ return ;
155+ }
156+ }
157+ else if (bk)
158+ {
159+ if (const auto ptr = query.get_block (query.to_header (hash), wit))
160+ {
161+ send_text (*request, encode_base16 (ptr->to_data (wit)));
162+ return ;
163+ }
164+ }
165+ else
166+ {
167+ if (const auto ptr = query.get_transaction (query.to_tx (hash), wit))
168+ {
169+ send_text (*request, encode_base16 (ptr->to_data (wit)));
170+ return ;
171+ }
172+ }
173+
120174 send_not_found (*request);
121175 return ;
122176 }
123-
124- send_data (*request, tx->to_data (true ));
125- return ;
126- }
127-
128- if (contains (accepts, text) || params[" format" ] == " text" )
129- {
130- const auto tx = get_tx (hex);
131- if (!tx)
177+ else if (is_data)
132178 {
179+ if (hd)
180+ {
181+ if (const auto ptr = query.get_header (query.to_header (hash)))
182+ {
183+ send_data (*request, ptr->to_data ());
184+ return ;
185+ }
186+ }
187+ else if (bk)
188+ {
189+ if (const auto ptr = query.get_block (query.to_header (hash), wit))
190+ {
191+ send_data (*request, ptr->to_data (wit));
192+ return ;
193+ }
194+ }
195+ else
196+ {
197+ if (const auto ptr = query.get_transaction (query.to_tx (hash), wit))
198+ {
199+ send_data (*request, ptr->to_data (wit));
200+ return ;
201+ }
202+ }
203+
133204 send_not_found (*request);
134205 return ;
135206 }
136-
137- send_text (*request, encode_base16 (tx->to_data (true )));
138- return ;
139207 }
140208
141209 // Default to html (single page site).
@@ -179,31 +247,31 @@ void protocol_explore::send_json(const request& request,
179247 response response{ status::ok, request.version () };
180248 add_common_headers (response, request);
181249 response.set (field::content_type, from_mime_type (json));
182- response.body () = { std::move (model) };
250+ response.body () = { std::move (model), std::make_shared<flat_buffer>( 10 * 1024 * 1024 ) };
183251 response.prepare_payload ();
184252 SEND (std::move (response), handle_complete, _1, error::success);
185253}
186254
187- void protocol_explore::send_data (const request& request,
188- data_chunk && data ) NOEXCEPT
255+ void protocol_explore::send_text (const request& request,
256+ std::string && hexidecimal ) NOEXCEPT
189257{
190258 BC_ASSERT_MSG (stranded (), " strand" );
191- data_response response{ status::ok, request.version () };
259+ string_response response{ status::ok, request.version () };
192260 add_common_headers (response, request);
193- response.set (field::content_type, from_mime_type (binary ));
194- response.body () = std::move (data );
261+ response.set (field::content_type, from_mime_type (text ));
262+ response.body () = std::move (hexidecimal );
195263 response.prepare_payload ();
196264 SEND (std::move (response), handle_complete, _1, error::success);
197265}
198266
199- void protocol_explore::send_text (const request& request,
200- std::string && hexidecimal ) NOEXCEPT
267+ void protocol_explore::send_data (const request& request,
268+ data_chunk && bytes ) NOEXCEPT
201269{
202270 BC_ASSERT_MSG (stranded (), " strand" );
203- string_response response{ status::ok, request.version () };
271+ data_response response{ status::ok, request.version () };
204272 add_common_headers (response, request);
205- response.set (field::content_type, from_mime_type (text ));
206- response.body () = std::move (hexidecimal );
273+ response.set (field::content_type, from_mime_type (data ));
274+ response.body () = std::move (bytes );
207275 response.prepare_payload ();
208276 SEND (std::move (response), handle_complete, _1, error::success);
209277}
0 commit comments