Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes issue #3891 #3923

Merged
merged 3 commits into from
Nov 8, 2012
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 63 additions & 5 deletions src/libstd/net_tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ pub fn TcpSocket(socket_data: @TcpSocketData) -> TcpSocket {
*/
struct TcpSocketBuf {
data: @TcpBufferedSocketData,
mut end_of_stream: bool,
}

pub fn TcpSocketBuf(data: @TcpBufferedSocketData) -> TcpSocketBuf {
TcpSocketBuf {
data: data
data: data,
end_of_stream: false
}
}

Expand Down Expand Up @@ -782,6 +784,7 @@ impl TcpSocketBuf: io::Reader {
let err_data = read_result.get_err();

if err_data.err_name == ~"EOF" {
self.end_of_stream = true;
break;
} else {
debug!("ERROR sock_buf as io::reader.read err %? %?",
Expand All @@ -808,13 +811,21 @@ impl TcpSocketBuf: io::Reader {
}
fn read_byte() -> int {
let mut bytes = ~[0];
if self.read(bytes, 1u) == 0 { fail } else { bytes[0] as int }
if self.read(bytes, 1u) == 0 {
if self.end_of_stream {
-1
} else {
fail
}
} else {
bytes[0] as int
}
}
fn unread_byte(amt: int) {
self.data.buf.unshift(amt as u8);
}
fn eof() -> bool {
false // noop
self.end_of_stream
}
fn seek(dist: int, seek: io::SeekStyle) {
log(debug, fmt!("tcp_socket_buf seek stub %? %?", dist, seek));
Expand Down Expand Up @@ -871,7 +882,8 @@ fn tear_down_socket_data(socket_data: @TcpSocketData) unsafe {
uv::ll::close(stream_handle_ptr, tcp_socket_dtor_close_cb);
};
core::comm::recv(closed_po);
log(debug, fmt!("about to free socket_data at %?", socket_data));
//the line below will most likely crash
//log(debug, fmt!("about to free socket_data at %?", socket_data));
rustrt::rust_uv_current_kernel_free(stream_handle_ptr
as *libc::c_void);
log(debug, ~"exiting dtor for tcp_socket");
Expand Down Expand Up @@ -1268,7 +1280,10 @@ mod test {
fn test_gl_tcp_ipv4_server_client_reader_writer() {
impl_gl_tcp_ipv4_server_client_reader_writer();
}

#[test]
fn test_tcp_socket_impl_reader_handles_eof() {
impl_tcp_socket_impl_reader_handles_eof();
}
}
#[cfg(target_arch="x86")]
mod impl32 {
Expand Down Expand Up @@ -1541,6 +1556,49 @@ mod test {
*/
}

fn impl_tcp_socket_impl_reader_handles_eof() {
use io::{Reader,ReaderUtil};
let hl_loop = uv::global_loop::get();
let server_ip = ~"127.0.0.1";
let server_port = 10041u;
let expected_req = ~"GET /";
let expected_resp = ~"A string\nwith multiple lines\n";

let server_result_po = core::comm::Port::<~str>();
let server_result_ch = core::comm::Chan(&server_result_po);

let cont_po = core::comm::Port::<()>();
let cont_ch = core::comm::Chan(&cont_po);
// server
do task::spawn_sched(task::ManualThreads(1u)) {
let actual_req = do comm::listen |server_ch| {
run_tcp_test_server(
server_ip,
server_port,
expected_resp,
server_ch,
cont_ch,
hl_loop)
};
server_result_ch.send(actual_req);
};
core::comm::recv(cont_po);
// client
log(debug, ~"server started, firing up client..");
let server_addr = ip::v4::parse_addr(server_ip);
let conn_result = connect(server_addr, server_port, hl_loop);
if result::is_err(&conn_result) {
assert false;
}
let sock_buf = @socket_buf(result::unwrap(move conn_result));
buf_write(sock_buf, expected_req);

let buf_reader = sock_buf as Reader;
let actual_response = str::from_bytes(buf_reader.read_whole_stream());
log(debug, fmt!("Actual response: %s", actual_response));
assert expected_resp == actual_response;
}

fn buf_write<W:io::Writer>(w: &W, val: &str) {
log(debug, fmt!("BUF_WRITE: val len %?", str::len(val)));
do str::byte_slice(val) |b_slice| {
Expand Down