1 #include <msp/core/except.h>
2 #include <msp/core/refptr.h>
3 #include <msp/net/resolve.h>
4 #include <msp/time/timedelta.h>
20 user_agent("libmsphttp/0.1"),
32 void Client::use_event_dispatcher(IO::EventDispatcher *ed)
34 if(event_disp && sock)
35 event_disp->remove(*sock);
37 if(event_disp && sock)
38 event_disp->add(*sock);
41 void Client::use_resolver(Net::Resolver *r)
45 delete resolve_listener;
51 resolve_listener = new ResolveListener(*this);
54 void Client::start_request(const Request &r)
57 throw invalid_state("already processing a request");
62 request = new Request(r);
63 if(!user_agent.empty())
64 request->set_header("User-Agent", user_agent);
70 string host = r.get_header("Host");
71 if(host.find(':')==string::npos)
74 resolve_tag = resolver->resolve(host);
77 RefPtr<Net::SockAddr> addr = Net::resolve(host);
78 address_resolved(resolve_tag, *addr);
82 const Response *Client::get_url(const std::string &url)
84 start_request(Request::from_url(url));
94 while(IO::PollEvent ev = IO::poll(*sock, sock->get_events(), Time::zero))
97 if(response && response->is_complete())
99 signal_response_complete.emit(*response);
108 void Client::wait_response()
110 while(request && (!response || !response->is_complete()))
122 void Client::address_resolved(unsigned tag, const Net::SockAddr &addr)
128 sock = new Net::StreamSocket(addr.get_family());
129 sock->set_block(false);
131 sock->signal_data_available.connect(sigc::mem_fun(this, &Client::data_available));
132 sock->signal_connect_finished.connect(sigc::mem_fun(this, &Client::connect_finished));
134 event_disp->add(*sock);
139 void Client::resolve_failed(unsigned tag, const exception &err)
148 if(signal_socket_error.empty())
150 signal_socket_error.emit(err);
153 void Client::connect_finished(const exception *err)
160 if(signal_socket_error.empty())
162 signal_socket_error.emit(*err);
168 sock->write(request->str());
170 catch(const exception &e)
172 if(signal_socket_error.empty())
174 signal_socket_error.emit(e);
180 void Client::data_available()
186 len = sock->read(rbuf, sizeof(rbuf));
188 catch(const exception &e)
190 if(signal_socket_error.empty())
192 signal_socket_error.emit(e);
198 in_buf.append(rbuf, len);
202 if(in_buf.find("\r\n\r\n")!=string::npos || in_buf.find("\n\n")!=string::npos)
204 response = new Response(Response::parse(in_buf));
205 response->set_user_data(request->get_user_data());
211 len = response->parse_content(in_buf);
212 in_buf.erase(0, len);
215 if(response && response->is_complete())
217 signal_response_complete.emit(*response);
225 Client::ResolveListener::ResolveListener(Client &c):
228 client.resolver->signal_address_resolved.connect(sigc::mem_fun(this, &ResolveListener::address_resolved));
229 client.resolver->signal_resolve_failed.connect(sigc::mem_fun(this, &ResolveListener::resolve_failed));
232 void Client::ResolveListener::address_resolved(unsigned tag, const Net::SockAddr &addr)
234 client.address_resolved(tag, addr);
237 void Client::ResolveListener::resolve_failed(unsigned tag, const exception &err)
239 client.resolve_failed(tag, err);