Skip to content

Commit

Permalink
Implement send method to send content along with the request
Browse files Browse the repository at this point in the history
  • Loading branch information
flaper87 committed Oct 5, 2013
1 parent d6372c4 commit a5c4eb3
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 9 deletions.
42 changes: 36 additions & 6 deletions src/examples/client/client.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
extern mod http;
use http::client::RequestWriter;
use http::method::Get;
use http::method::{Get, Post};
use http::headers::HeaderEnum;
use std::str;
use std::rt::io::extensions::ReaderUtil;
use std::rt::io::net::ip::{SocketAddr, Ipv4Addr};

fn main() {
let mut request = ~RequestWriter::new(Get, FromStr::from_str("http://localhost/example")
fn get_request() {
let request = ~RequestWriter::new(Get, FromStr::from_str("http://httpbin.org/get")
.expect("Uh oh, that's *really* badly broken!"));
// Temporary measure, as hostname lookup is not yet supported in std::rt::io.
request.remote_addr = Some(SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 8001 });

let mut response = match request.read_response() {
Ok(response) => response,
Err(_request) => fail!("This example can progress no further with no response :-("),
};

println("Yay! Started to get the response.");
println!("Status: {}", response.status);
println("Headers:");
Expand All @@ -25,3 +24,34 @@ fn main() {
println("Response:");
println(str::from_utf8(response.read_to_end()));
}


fn post_request() {
let mut request = ~RequestWriter::new(Post, FromStr::from_str("http://httpbin.org/post")
.expect("Uh oh, that's *really* badly broken!"));

request.send("Post It!".as_bytes());

let mut response = match request.read_response() {
Ok(response) => response,
Err(_request) => fail!("This example can progress no further with no response :-("),
};

println("Yay! Started to get the response.");
println!("Status: {}", response.status);
println("Headers:");
for header in response.headers.iter() {
println!(" - {}: {}", header.header_name(), header.header_value());
}

print("\n");
println("Response:");
println(str::from_utf8(response.read_to_end()));
}

fn main() {

get_request();

post_request();
}
33 changes: 30 additions & 3 deletions src/libhttp/client/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,33 @@ impl RequestWriter<TcpStream> {
let s = format!("{} {} HTTP/1.0\r\n", self.method.to_str(), self.url.to_str());
self.stream.write(s.as_bytes());

// `write_all` adds '\r\n' at the end, no
// need to terminate the headers section
// here.
self.headers.write_all(&mut self.stream);
self.headers_written = true;
}

/// Send data to the remote server.
/// This method appends Content-Length
/// to headers and sends them. If headers
/// where already sent, it will send data
/// without the Content-Length.
// TODO: Implement chunked request, perhaps
// in a `send_chunked` method.
pub fn send(&mut self, buf: &[u8]) {

// NOTE: Should we make this fail?
// If 'Content-Length' is not sent
// some servers won't read the request
// body.
if !self.headers_written {
self.headers.content_length = Some(buf.len());
self.write_headers();
}
self.write(buf);
}

// FIXME: ~self rather than self to work around a Rust bug in by-val self at present leading to
// a segfault on calling construct().
pub fn read_response(~self) -> Result<ResponseReader<TcpStream>, ~RequestWriter<TcpStream>> {
Expand All @@ -185,9 +208,13 @@ impl RequestWriter<TcpStream> {

impl Writer for RequestWriter<TcpStream> {
fn write(&mut self, buf: &[u8]) {
if (!self.headers_written) {
self.write_headers();
}
// No data must be sent before
// sending headers. Let's make
// sure that's the case.
self.try_write_headers();

// Now we're good to send
// some data.
self.stream.write(buf);
}

Expand Down

0 comments on commit a5c4eb3

Please sign in to comment.