aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTill Hoeppner2015-05-04 20:09:59 +0200
committerTill Hoeppner2015-05-04 20:09:59 +0200
commite1d4270acbb12306f5e30927b4f05ff2ff6c6937 (patch)
tree364025d9a7b5378eee6b7cf37734cd35dec2f0d6
parent4a092fd5ecccd1822c33702663701ad63953aa54 (diff)
downloadirsc-e1d4270acbb12306f5e30927b4f05ff2ff6c6937.tar.gz
irsc-e1d4270acbb12306f5e30927b4f05ff2ff6c6937.tar.xz
irsc-e1d4270acbb12306f5e30927b4f05ff2ff6c6937.zip
Add SSL connections and use them in the example
-rw-r--r--examples/01.rs15
-rw-r--r--src/client.rs22
-rw-r--r--src/lib.rs14
3 files changed, 40 insertions, 11 deletions
diff --git a/examples/01.rs b/examples/01.rs
index 345adba..595bc70 100644
--- a/examples/01.rs
+++ b/examples/01.rs
@@ -1,4 +1,5 @@
extern crate irsc;
+extern crate env_logger;
use std::borrow::ToOwned;
use std::borrow::Cow::*;
@@ -20,7 +21,12 @@ fn callback(server: &mut Client, msg: &Message) {
MsgType::Irc => format!("{} wrote: {}", from.nickname, bold(&content)),
MsgType::Ctcp => format!("{} emoted: {}", from.nickname, bold(&content["ACTION ".len()..]))
};
- server.send(PRIVMSG(to, Owned(response))).unwrap();
+
+ // only send to channels, to prevent recursion when we are pm'ed
+ // technically, there are other prefixes than '#', but ignoring them is fine
+ if to.starts_with("#") {
+ server.send(PRIVMSG(to, Owned(response))).unwrap();
+ }
},
_ => ()
}
@@ -34,8 +40,13 @@ fn callback(server: &mut Client, msg: &Message) {
}
fn main() {
+ env_logger::init().unwrap();
let mut s = Client::new();
- s.connect("irc.mozilla.org".to_owned(), 6667).unwrap();
+ if cfg!(feature = "ssl") {
+ s.connect_ssl("irc.mozilla.org".to_owned(), 6697).unwrap();
+ } else {
+ s.connect("irc.mozilla.org".to_owned(), 6667).unwrap();
+ }
s.send(NICK(Borrowed(NAME))).unwrap();
s.send(USER(Borrowed(NAME), Borrowed("*"), Borrowed("*"), Borrowed(DESC))).unwrap();
diff --git a/src/client.rs b/src/client.rs
index a738262..a688565 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -20,7 +20,7 @@ use openssl::ssl::{ SslContext, SslMethod, SslStream };
enum StreamKind {
Plain(TcpStream),
#[cfg(feature = "ssl")]
- Ssl(SslStream)
+ Ssl(SslStream<TcpStream>)
}
impl Write for StreamKind {
@@ -82,18 +82,24 @@ impl Client {
#[cfg(feature = "ssl")]
pub fn connect_ssl(&mut self, host: String, port: u16) -> Result<()> {
- let mut s = self.stream.lock();
+ let s = &mut self.stream;
match *s { Some(_) => return Err(IrscError::AlreadyConnected), _ => () };
let tcp_stream = match TcpStream::connect((host.as_ref(), port)) {
Ok(tcp) => Some(tcp),
Err(e) => return Err(IrscError::Io(e))
};
- let ssl = SslContext::new(SslMethod::Tlsv1);
- let ssl_stream = SslStream::new(&ssl, tcp_stream);
- *s = ssl_stream;
+ let ssl = try!(SslContext::new(SslMethod::Tlsv1));
+ match tcp_stream.map(|tcp| SslStream::new(&ssl, tcp)) {
+ Some(Ok(ssl_stream)) => { *s = Some(StreamKind::Ssl(ssl_stream)); Ok(()) },
+ Some(Err(ssl_error)) => Err(IrscError::Ssl(ssl_error)),
+ None => Err(IrscError::NotConnected)
+ }
+ }
- Ok(())
+ #[cfg(not(feature = "ssl"))]
+ pub fn connect_ssl(&mut self, _host: String, _port: u16) -> Result<()> {
+ panic!("Not compiled with ssl feature.")
}
#[inline]
@@ -121,9 +127,9 @@ impl Client {
pub fn listen<F>(&mut self, events: F) -> Result<()>
where F: Fn(&mut Client, &Message) {
let reader = BufReader::new(match self.stream {
- Some(StreamKind::Plain(ref s)) => (*s).try_clone().unwrap(),
+ Some(StreamKind::Plain(ref s)) => StreamKind::Plain((*s).try_clone().unwrap()),
#[cfg(feature = "ssl")]
- Some(StreamKind::Ssl(ref s)) => (*s).try_clone().unwrap(),
+ Some(StreamKind::Ssl(ref s)) => StreamKind::Ssl((*s).try_clone().unwrap()),
None => return Err(IrscError::NotConnected)
});
diff --git a/src/lib.rs b/src/lib.rs
index a4da317..6ec60db 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -7,6 +7,8 @@
extern crate regex;
#[macro_use]
extern crate log;
+#[cfg(feature = "ssl")]
+extern crate openssl;
pub mod client;
pub mod color;
@@ -19,6 +21,9 @@ pub mod reply;
use std::io;
use std::result;
+#[cfg(feature = "ssl")]
+use openssl::ssl::error::SslError;
+
pub use ident::Ident;
pub use message::{ Message, MsgType };
pub use command::Command;
@@ -29,7 +34,14 @@ pub enum IrscError {
Io(io::Error),
AlreadyConnected,
NotConnected,
- NotFound
+ NotFound,
+ #[cfg(feature = "ssl")]
+ Ssl(SslError)
+}
+
+#[cfg(feature = "ssl")]
+impl From<SslError> for IrscError {
+ fn from(e: SslError) -> IrscError { IrscError::Ssl(e) }
}
pub type Result<T> = result::Result<T, IrscError>;