feat(docker): added StreamFormatReader
							parent
							
								
									92cbea69d6
								
							
						
					
					
						commit
						f22ed29631
					
				| 
						 | 
				
			
			@ -168,6 +168,21 @@ pub fn remove_container(id string) ?bool {
 | 
			
		|||
	return res.status_code == 204
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn (mut d DockerDaemon) get_container_logs(id string) ?&StreamFormatReader {
 | 
			
		||||
	d.send_request('GET', urllib.parse('/v1.41/containers/$id/logs?stdout=true&stderr=true')?)?
 | 
			
		||||
	head := d.read_response_head()?
 | 
			
		||||
 | 
			
		||||
	if head.status_code != 200 {
 | 
			
		||||
		content_length := head.header.get(http.CommonHeader.content_length)?.int()
 | 
			
		||||
		body := d.read_response_body(content_length)?
 | 
			
		||||
		data := json.decode(DockerError, body)?
 | 
			
		||||
 | 
			
		||||
		return error(data.message)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return d.get_stream_format_reader()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get_container_logs retrieves the logs for a Docker container, both stdout &
 | 
			
		||||
// stderr.
 | 
			
		||||
pub fn get_container_logs(id string) ?string {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -123,3 +123,10 @@ pub fn (mut d DockerDaemon) get_chunked_response_reader() &ChunkedResponseReader
 | 
			
		|||
 | 
			
		||||
	return r
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn (mut d DockerDaemon) get_stream_format_reader() &StreamFormatReader {
 | 
			
		||||
	r := new_chunked_response_reader(d.reader)
 | 
			
		||||
	r2 := new_stream_format_reader(r)
 | 
			
		||||
 | 
			
		||||
	return r2
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,13 +7,10 @@ import encoding.hex
 | 
			
		|||
 | 
			
		||||
struct ChunkedResponseReader {
 | 
			
		||||
mut:
 | 
			
		||||
	reader io.Reader
 | 
			
		||||
	// buf []u8
 | 
			
		||||
	// offset int
 | 
			
		||||
	// len int
 | 
			
		||||
	reader              io.Reader
 | 
			
		||||
	bytes_left_in_chunk u64
 | 
			
		||||
	end_of_stream       bool
 | 
			
		||||
	started bool
 | 
			
		||||
	started             bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn new_chunked_response_reader(reader io.Reader) &ChunkedResponseReader {
 | 
			
		||||
| 
						 | 
				
			
			@ -56,8 +53,8 @@ fn (mut r ChunkedResponseReader) read_chunk_size() ?u64 {
 | 
			
		|||
	mut res := []u8{}
 | 
			
		||||
 | 
			
		||||
	if r.started {
 | 
			
		||||
	// Each chunk ends with a `\r\n` which we want to skip first
 | 
			
		||||
	r.reader.read(mut buf) ?
 | 
			
		||||
		// Each chunk ends with a `\r\n` which we want to skip first
 | 
			
		||||
		r.reader.read(mut buf)?
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r.started = true
 | 
			
		||||
| 
						 | 
				
			
			@ -85,9 +82,9 @@ fn (mut r ChunkedResponseReader) read_chunk_size() ?u64 {
 | 
			
		|||
 | 
			
		||||
	mut num_data := hex.decode(res#[..-2].bytestr())?
 | 
			
		||||
 | 
			
		||||
		for num_data.len < 8 {
 | 
			
		||||
			num_data.insert(0, 0)
 | 
			
		||||
		}
 | 
			
		||||
	for num_data.len < 8 {
 | 
			
		||||
		num_data.insert(0, 0)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	num := binary.big_endian_u64(num_data)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -97,3 +94,57 @@ fn (mut r ChunkedResponseReader) read_chunk_size() ?u64 {
 | 
			
		|||
 | 
			
		||||
	return num
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct StreamFormatReader {
 | 
			
		||||
	stdout bool
 | 
			
		||||
	stderr bool
 | 
			
		||||
	stdin  bool
 | 
			
		||||
mut:
 | 
			
		||||
	reader              io.Reader
 | 
			
		||||
	bytes_left_in_chunk u32
 | 
			
		||||
	end_of_stream       bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn new_stream_format_reader(reader io.Reader) &StreamFormatReader {
 | 
			
		||||
	r := &StreamFormatReader{
 | 
			
		||||
		reader: reader
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return r
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn (mut r StreamFormatReader) read(mut buf []u8) ?int {
 | 
			
		||||
	if r.end_of_stream {
 | 
			
		||||
		return none
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if r.bytes_left_in_chunk == 0 {
 | 
			
		||||
		r.bytes_left_in_chunk = r.read_chunk_size()?
 | 
			
		||||
 | 
			
		||||
		if r.end_of_stream {
 | 
			
		||||
			return none
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mut c := 0
 | 
			
		||||
 | 
			
		||||
	if buf.len > r.bytes_left_in_chunk {
 | 
			
		||||
		c = r.reader.read(mut buf[..r.bytes_left_in_chunk])?
 | 
			
		||||
	} else {
 | 
			
		||||
		c = r.reader.read(mut buf)?
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r.bytes_left_in_chunk -= u32(c)
 | 
			
		||||
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn (mut r StreamFormatReader) read_chunk_size() ?u32 {
 | 
			
		||||
	mut buf := []u8{len: 8}
 | 
			
		||||
 | 
			
		||||
	r.reader.read(mut buf)?
 | 
			
		||||
 | 
			
		||||
	num := binary.big_endian_u32(buf[4..])
 | 
			
		||||
 | 
			
		||||
	return num
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue