Skip to content

Instantly share code, notes, and snippets.

@megumish
Created March 13, 2018 17:18
Show Gist options
  • Save megumish/b194bf29e905916e65a583a7203e79fe to your computer and use it in GitHub Desktop.
Save megumish/b194bf29e905916e65a583a7203e79fe to your computer and use it in GitHub Desktop.
tokio muzui
#![deny(missing_docs)]
use tokio;
use tokio::prelude::*;
use tokio::net::{TcpStream, ConnectFuture};
use std::net::ToSocketAddrs;
use std::{thread, time};
use futures::prelude::*;
use futures::future::FutureResult;
use url::{self, Url, Host};
use std::error;
use std::fmt;
use std::convert;
use std::io;
#[derive(Debug)]
struct HttpBody {
text: String
}
#[derive(Debug)]
struct HttpResponse {
body: HttpBody,
}
impl HttpResponse {
fn new<S: Into<String>>(body_text: S) -> Self {
HttpResponse {
body: HttpBody {
text: body_text.into()
}
}
}
}
#[derive(Debug)]
enum HttpResponseError {
NotHttpScheme,
ParseURL(url::ParseError),
Io(io::Error)
}
impl fmt::Display for HttpResponseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
HttpResponseError::NotHttpScheme => write!(f, "Not HTTP Scheme: input string hasn't http scheme"),
HttpResponseError::ParseURL(ref err) => write!(f, "Parse URL Error: {}", err),
HttpResponseError::Io(ref err) => write!(f, "IO Error: {}", err),
}
}
}
impl error::Error for HttpResponseError {
fn description(&self) -> &str {
match *self {
HttpResponseError::NotHttpScheme => "This hasn't http scheme",
HttpResponseError::ParseURL(ref err) => err.description(),
HttpResponseError::Io(ref err) => err.description(),
}
}
fn cause(&self) -> Option<&error::Error> {
match *self {
HttpResponseError::NotHttpScheme => Some(&HttpResponseError::NotHttpScheme),
HttpResponseError::ParseURL(ref err) => Some(err),
HttpResponseError::Io(ref err) => Some(err),
}
}
}
impl convert::From<url::ParseError> for HttpResponseError {
fn from(err: url::ParseError) -> HttpResponseError {
HttpResponseError::ParseURL(err)
}
}
impl convert::From<io::Error> for HttpResponseError {
fn from(err: io::Error) -> HttpResponseError {
HttpResponseError::Io(err)
}
}
struct SimpleClient {}
impl SimpleClient {
fn new() -> Self {
SimpleClient{}
}
fn get<S: Into<String>>(&self, url: S) -> Result<HttpResponse, HttpResponseError> {
let issue_list_url = Url::parse(&url.into())?;
if issue_list_url.scheme() != "http" {
return Err(HttpResponseError::NotHttpScheme)
}
if let Ok(mut socket_addrs) = issue_list_url.to_socket_addrs() {
let socket_addr = socket_addrs.next().unwrap();
let connect_future = TcpStream::connect(&socket_addr);
let task = connect_future
.and_then(|mut socket| {
let buffer = "GET / HTTP/2.0\nHost: localhost\nConnection: keep-alive\n\n".as_bytes();
loop {
match socket.poll_write(buffer) {
Ok(Async::Ready(_)) => break,
Err(err) => eprintln!("Error: {:?}", err),
_ => {},
}
let milli = time::Duration::from_millis(1);
let now = time::Instant::now();
thread::sleep(milli);
}
let mut buffer = vec![0; 1024];
loop {
match socket.poll_read(&mut buffer) {
Err(err) => eprintln!("Error: {:?}", err),
_ => {},
}
let milli = time::Duration::from_millis(1);
let now = time::Instant::now();
thread::sleep(milli);
eprintln!("input: {:?}", String::from_utf8(buffer.clone()).unwrap());
}
Ok(())
})
.map_err(|err| eprintln!("Error: {:?}", err));
tokio::run(task);
Ok(HttpResponse::new("Hello World!"))
} else {
Ok(HttpResponse::new("Hello World!"))
}
}
}
#[test]
fn simple_get_http() {
let client = SimpleClient::new();
let response = client.get("http://127.0.0.1/").unwrap();
let body_text = response.body.text;
assert_eq!("Hello World!", body_text);
//let response = client.get("http://127.0.0.1:81/").unwrap();
//let body_text = response.body.text;
//assert_eq!("Hello World?", body_text);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment