summaryrefslogtreecommitdiffstats
path: root/examples/proxy.rs
diff options
context:
space:
mode:
authorEliza Weisman <eliza@buoyant.io>2019-03-22 15:25:42 -0700
committerGitHub <noreply@github.com>2019-03-22 15:25:42 -0700
commit30330da11a56dfdd11bdbef50dba073a9edc36b2 (patch)
treebf4e8e90293a3c75a2bf5281572e1c01eceab3cb /examples/proxy.rs
parent6e4945025cdc6f2b71d9b30aaa23c5517cca1504 (diff)
chore: Fix examples not working with `cargo run` (#998)
* chore: Fix examples not working with `cargo run` ## Motivation PR #991 moved the `tokio` crate to its own subdirectory, but did not move the `examples` directory into `tokio/examples`. While attempting to use the examples for testing another change, I noticed that #991 had broken the ability to use `cargo run`, as the examples were no longer considered part of a crate that cargo was aware of: ``` tokio on master [$] via 🦀v1.33.0 at ☸️ aks-eliza-dev ➜ cargo run --example chat error: no example target named `chat` Did you mean `echo`? ``` ## Solution This branch moves the examples into the `tokio` directory, so cargo is now once again aware of them: ``` tokio on eliza/fix-examples [$] via 🦀v1.33.0 at ☸️ aks-eliza-dev ➜ cargo run --example chat Compiling tokio-executor v0.1.7 (/Users/eliza/Code/tokio/tokio-executor) Compiling tokio-reactor v0.1.9 Compiling tokio-threadpool v0.1.13 Compiling tokio-current-thread v0.1.6 Compiling tokio-timer v0.2.10 Compiling tokio-uds v0.2.5 Compiling tokio-udp v0.1.3 Compiling tokio-tcp v0.1.3 Compiling tokio-fs v0.1.6 Compiling tokio v0.1.18 (/Users/eliza/Code/tokio/tokio) Finished dev [unoptimized + debuginfo] target(s) in 7.04s Running `target/debug/examples/chat` server running on localhost:6142 ``` Signed-off-by: Eliza Weisman <eliza@buoyant.io> Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Diffstat (limited to 'examples/proxy.rs')
-rw-r--r--examples/proxy.rs130
1 files changed, 0 insertions, 130 deletions
diff --git a/examples/proxy.rs b/examples/proxy.rs
deleted file mode 100644
index ae8bf3a4..00000000
--- a/examples/proxy.rs
+++ /dev/null
@@ -1,130 +0,0 @@
-//! A proxy that forwards data to another server and forwards that server's
-//! responses back to clients.
-//!
-//! Because the Tokio runtime uses a thread pool, each TCP connection is
-//! processed concurrently with all other TCP connections across multiple
-//! threads.
-//!
-//! You can showcase this by running this in one terminal:
-//!
-//! cargo run --example proxy
-//!
-//! This in another terminal
-//!
-//! cargo run --example echo
-//!
-//! And finally this in another terminal
-//!
-//! cargo run --example connect 127.0.0.1:8081
-//!
-//! This final terminal will connect to our proxy, which will in turn connect to
-//! the echo server, and you'll be able to see data flowing between them.
-
-#![deny(warnings)]
-
-extern crate tokio;
-
-use std::env;
-use std::io::{self, Read, Write};
-use std::net::{Shutdown, SocketAddr};
-use std::sync::{Arc, Mutex};
-
-use tokio::io::{copy, shutdown};
-use tokio::net::{TcpListener, TcpStream};
-use tokio::prelude::*;
-
-fn main() -> Result<(), Box<std::error::Error>> {
- let listen_addr = env::args().nth(1).unwrap_or("127.0.0.1:8081".to_string());
- let listen_addr = listen_addr.parse::<SocketAddr>()?;
-
- let server_addr = env::args().nth(2).unwrap_or("127.0.0.1:8080".to_string());
- let server_addr = server_addr.parse::<SocketAddr>()?;
-
- // Create a TCP listener which will listen for incoming connections.
- let socket = TcpListener::bind(&listen_addr)?;
- println!("Listening on: {}", listen_addr);
- println!("Proxying to: {}", server_addr);
-
- let done = socket
- .incoming()
- .map_err(|e| println!("error accepting socket; error = {:?}", e))
- .for_each(move |client| {
- let server = TcpStream::connect(&server_addr);
- let amounts = server.and_then(move |server| {
- // Create separate read/write handles for the TCP clients that we're
- // proxying data between. Note that typically you'd use
- // `AsyncRead::split` for this operation, but we want our writer
- // handles to have a custom implementation of `shutdown` which
- // actually calls `TcpStream::shutdown` to ensure that EOF is
- // transmitted properly across the proxied connection.
- //
- // As a result, we wrap up our client/server manually in arcs and
- // use the impls below on our custom `MyTcpStream` type.
- let client_reader = MyTcpStream(Arc::new(Mutex::new(client)));
- let client_writer = client_reader.clone();
- let server_reader = MyTcpStream(Arc::new(Mutex::new(server)));
- let server_writer = server_reader.clone();
-
- // Copy the data (in parallel) between the client and the server.
- // After the copy is done we indicate to the remote side that we've
- // finished by shutting down the connection.
- let client_to_server = copy(client_reader, server_writer)
- .and_then(|(n, _, server_writer)| shutdown(server_writer).map(move |_| n));
-
- let server_to_client = copy(server_reader, client_writer)
- .and_then(|(n, _, client_writer)| shutdown(client_writer).map(move |_| n));
-
- client_to_server.join(server_to_client)
- });
-
- let msg = amounts
- .map(move |(from_client, from_server)| {
- println!(
- "client wrote {} bytes and received {} bytes",
- from_client, from_server
- );
- })
- .map_err(|e| {
- // Don't panic. Maybe the client just disconnected too soon.
- println!("error: {}", e);
- });
-
- tokio::spawn(msg);
-
- Ok(())
- });
-
- tokio::run(done);
- Ok(())
-}
-
-// This is a custom type used to have a custom implementation of the
-// `AsyncWrite::shutdown` method which actually calls `TcpStream::shutdown` to
-// notify the remote end that we're done writing.
-#[derive(Clone)]
-struct MyTcpStream(Arc<Mutex<TcpStream>>);
-
-impl Read for MyTcpStream {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- self.0.lock().unwrap().read(buf)
- }
-}
-
-impl Write for MyTcpStream {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- self.0.lock().unwrap().write(buf)
- }
-
- fn flush(&mut self) -> io::Result<()> {
- Ok(())
- }
-}
-
-impl AsyncRead for MyTcpStream {}
-
-impl AsyncWrite for MyTcpStream {
- fn shutdown(&mut self) -> Poll<(), io::Error> {
- try!(self.0.lock().unwrap().shutdown(Shutdown::Write));
- Ok(().into())
- }
-}