1 #include <msp/core/except.h>
2 #include <msp/net/resolve.h>
3 #include <msp/time/timedelta.h>
17 void Client::use_event_dispatcher(IO::EventDispatcher *ed)
19 if(event_disp && sock)
20 event_disp->remove(*sock);
22 if(event_disp && sock)
23 event_disp->add(*sock);
26 void Client::use_resolver(Net::Resolver *r)
29 resolve_listener.reset();
33 resolve_listener = make_unique<ResolveListener>(*this);
36 void Client::start_request(const Request &r)
39 throw invalid_state("already processing a request");
43 request = make_unique<Request>(r);
44 if(!user_agent.empty())
45 request->set_header("User-Agent", user_agent);
50 string host = r.get_header("Host");
51 if(host.find(':')==string::npos)
54 resolve_tag = resolver->resolve(host);
57 unique_ptr<Net::SockAddr> addr(Net::resolve(host));
58 address_resolved(resolve_tag, *addr);
62 const Response *Client::get_url(const std::string &url)
64 start_request(Request::from_url(url));
66 return response.get();
74 while(IO::PollEvent ev = IO::poll(*sock, sock->get_events(), Time::zero))
77 if(response && response->is_complete())
79 signal_response_complete.emit(*response);
86 void Client::wait_response()
88 while(request && (!response || !response->is_complete()))
98 void Client::address_resolved(unsigned tag, const Net::SockAddr &addr)
104 sock = make_unique<Net::StreamSocket>(addr.get_family());
105 sock->set_block(false);
107 sock->signal_data_available.connect(sigc::mem_fun(this, &Client::data_available));
108 sock->signal_connect_finished.connect(sigc::mem_fun(this, &Client::connect_finished));
110 event_disp->add(*sock);
115 void Client::resolve_failed(unsigned tag, const exception &err)
123 if(signal_socket_error.empty())
125 signal_socket_error.emit(err);
128 void Client::connect_finished(const exception *err)
134 if(signal_socket_error.empty())
136 signal_socket_error.emit(*err);
142 sock->write(request->str());
144 catch(const exception &e)
146 if(signal_socket_error.empty())
148 signal_socket_error.emit(e);
154 void Client::data_available()
160 len = sock->read(rbuf, sizeof(rbuf));
162 catch(const exception &e)
164 if(signal_socket_error.empty())
166 signal_socket_error.emit(e);
172 in_buf.append(rbuf, len);
176 if(in_buf.find("\r\n\r\n")!=string::npos || in_buf.find("\n\n")!=string::npos)
178 response = make_unique<Response>(Response::parse(in_buf));
179 response->set_user_data(request->get_user_data());
185 len = response->parse_content(in_buf);
186 in_buf.erase(0, len);
189 if(response && response->is_complete())
191 signal_response_complete.emit(*response);
198 Client::ResolveListener::ResolveListener(Client &c):
201 client.resolver->signal_address_resolved.connect(sigc::mem_fun(this, &ResolveListener::address_resolved));
202 client.resolver->signal_resolve_failed.connect(sigc::mem_fun(this, &ResolveListener::resolve_failed));
205 void Client::ResolveListener::address_resolved(unsigned tag, const Net::SockAddr &addr)
207 client.address_resolved(tag, addr);
210 void Client::ResolveListener::resolve_failed(unsigned tag, const exception &err)
212 client.resolve_failed(tag, err);