1 use libc::size_t; 2 3 /// A more detailed error object returned by some hyper functions. 4 pub struct hyper_error(crate::Error); 5 6 /// A return code for many of hyper's methods. 7 #[repr(C)] 8 pub enum hyper_code { 9 /// All is well. 10 HYPERE_OK, 11 /// General error, details in the `hyper_error *`. 12 HYPERE_ERROR, 13 /// A function argument was invalid. 14 HYPERE_INVALID_ARG, 15 /// The IO transport returned an EOF when one wasn't expected. 16 /// 17 /// This typically means an HTTP request or response was expected, but the 18 /// connection closed cleanly without sending (all of) it. 19 HYPERE_UNEXPECTED_EOF, 20 /// Aborted by a user supplied callback. 21 HYPERE_ABORTED_BY_CALLBACK, 22 /// An optional hyper feature was not enabled. 23 #[cfg_attr(feature = "http2", allow(unused))] 24 HYPERE_FEATURE_NOT_ENABLED, 25 /// The peer sent an HTTP message that could not be parsed. 26 HYPERE_INVALID_PEER_MESSAGE, 27 } 28 29 // ===== impl hyper_error ===== 30 31 impl hyper_error { 32 fn code(&self) -> hyper_code { 33 use crate::error::Kind as ErrorKind; 34 use crate::error::User; 35 36 match self.0.kind() { 37 ErrorKind::Parse(_) => hyper_code::HYPERE_INVALID_PEER_MESSAGE, 38 ErrorKind::IncompleteMessage => hyper_code::HYPERE_UNEXPECTED_EOF, 39 ErrorKind::User(User::AbortedByCallback) => hyper_code::HYPERE_ABORTED_BY_CALLBACK, 40 // TODO: add more variants 41 _ => hyper_code::HYPERE_ERROR, 42 } 43 } 44 45 fn print_to(&self, dst: &mut [u8]) -> usize { 46 use std::io::Write; 47 48 let mut dst = std::io::Cursor::new(dst); 49 50 // A write! error doesn't matter. As much as possible will have been 51 // written, and the Cursor position will know how far that is (even 52 // if that is zero). 53 let _ = write!(dst, "{}", &self.0); 54 dst.position() as usize 55 } 56 } 57 58 ffi_fn! { 59 /// Frees a `hyper_error`. 60 fn hyper_error_free(err: *mut hyper_error) { 61 drop(non_null!(Box::from_raw(err) ?= ())); 62 } 63 } 64 65 ffi_fn! { 66 /// Get an equivalent `hyper_code` from this error. 67 fn hyper_error_code(err: *const hyper_error) -> hyper_code { 68 non_null!(&*err ?= hyper_code::HYPERE_INVALID_ARG).code() 69 } 70 } 71 72 ffi_fn! { 73 /// Print the details of this error to a buffer. 74 /// 75 /// The `dst_len` value must be the maximum length that the buffer can 76 /// store. 77 /// 78 /// The return value is number of bytes that were written to `dst`. 79 fn hyper_error_print(err: *const hyper_error, dst: *mut u8, dst_len: size_t) -> size_t { 80 let dst = unsafe { 81 std::slice::from_raw_parts_mut(dst, dst_len) 82 }; 83 non_null!(&*err ?= 0).print_to(dst) 84 } 85 } 86