11 #include <boost/algorithm/string.hpp> 22 int read_until(
char* buffer,
char* end,
char c =
'\n' ) {
25 while( p < end && 1 == sock.
readsome(p,1) ) {
28 return (p - buffer)-1;
42 std::vector<char> line(1024*8);
43 int s =
read_until( line.data(), line.data()+line.size(),
' ' );
44 s =
read_until( line.data(), line.data()+line.size(),
' ' );
46 s =
read_until( line.data(), line.data()+line.size(),
'\n' );
48 while( (s =
read_until( line.data(), line.data()+line.size(),
'\n' )) > 1 ) {
50 char* end = line.data();
51 while( *end !=
':' )++end;
52 h.
key = std::string(line.data(),end);
56 while( *end !=
'\r' ) ++end;
57 h.
val = std::string(skey,end);
59 if( boost::iequals(h.
key,
"Content-Length") ) {
63 if( rep.
body.size() ) {
78 namespace fc {
namespace http {
88 my->sock.connect_to( my->ep = ep );
92 const std::string&
url,
93 const std::string& body,
const headers& he ) {
96 if( !my->sock.is_open() ) {
97 wlog(
"Re-open socket!" );
98 my->sock.connect_to( my->ep );
103 req <<
"Host: "<<*parsed_url.
host()<<
"\r\n";
104 req <<
"Content-Type: application/json\r\n";
105 for(
auto i = he.begin(); i != he.end(); ++i )
107 req << i->key <<
": " << i->val<<
"\r\n";
109 if( body.size() ) req <<
"Content-Length: "<< body.size() <<
"\r\n";
111 std::string head = req.
str();
113 my->sock.write( head.c_str(), head.size() );
117 my->sock.write( body.c_str(), body.size() );
122 return my->parse_reply();
138 std::vector<char> line(1024*8);
139 int s = my->read_until( line.data(), line.data()+line.size(),
' ' );
141 s = my->read_until( line.data(), line.data()+line.size(),
' ' );
142 req.
path = line.data();
143 s = my->read_until( line.data(), line.data()+line.size(),
'\n' );
145 while( (s = my->read_until( line.data(), line.data()+line.size(),
'\n' )) > 1 ) {
147 char* end = line.data();
148 while( *end !=
':' )++end;
149 h.
key = std::string(line.data(),end);
153 while( *end !=
'\r' ) ++end;
154 h.
val = std::string(skey,end);
156 if( boost::iequals(h.
key,
"Content-Length")) {
157 auto s =
static_cast<size_t>(
to_uint64( std::string(h.
val) ) );
161 if( boost::iequals(h.
key,
"Host") ) {
168 if( req.
body.size() ) {
169 my->sock.read( req.
body.data(), req.
body.size() );
176 if( boost::iequals(itr->key, key) ) {
return itr->val; }
178 return std::string();
182 for(
size_t i = 0; i < f.size(); ++i ) {
183 if( f[i] ==
'=' ) ++num_args;
185 std::vector<header> h(num_args);
187 for(
size_t i = 0; i < f.size(); ++i ) {
188 while( i < f.size() && f[i] !=
'=' ) {
198 while( i < f.size() && f[i] !=
'&' ) {
203 h[arg].val += f[i] ==
'+' ?
' ' : f[i];
std::vector< header > parse_urlencoded_params(const std::string &f)
istream & read(char *buf, size_t len)
http::reply request(const std::string &method, const std::string &url, const std::string &body=std::string(), const headers &=headers())
std::string get_header(const std::string &key) const
std::vector< header > headers
void connect_to(const fc::ip::endpoint &ep)
Used to generate a useful error report when an exception is thrown.At each level in the stack where t...
int64_t to_int64(const std::string &)
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
virtual size_t readsome(char *buffer, size_t max)
uint64_t to_uint64(const std::string &)
std::string generic_string() const
Defines exception's used by fc.
std::string to_detail_string(log_level ll=log_level::all) const
std::string remote_endpoint
fc::http::reply parse_reply()
std::vector< header > headers
fc::tcp_socket & get_socket() const
http::request read_request() const
int read_until(char *buffer, char *end, char c='\n')
std::vector< header > headers