mirror of https://github.com/rwf2/Rocket.git
Remove unneeded lifetime in Request.
Previously, a Request's only lifetime parameter referred to itself. This causes many issues and is simply wrong. Instead, use `transmute` to make the lifetime `static`. As long the contents inside Request don't move or change, the references are valid. We keep the lifetime as a phantom in `Request` for future use.
This commit is contained in:
parent
bcb9bd860b
commit
39f7f2d32b
|
@ -34,11 +34,10 @@ pub struct Request<'a> {
|
||||||
/// The data in the request.
|
/// The data in the request.
|
||||||
pub data: Vec<u8>, // FIXME: Don't read this! (bad Hyper.)
|
pub data: Vec<u8>, // FIXME: Don't read this! (bad Hyper.)
|
||||||
uri: URIBuf, // FIXME: Should be URI (without Hyper).
|
uri: URIBuf, // FIXME: Should be URI (without Hyper).
|
||||||
|
params: RefCell<Vec<&'static str>>,
|
||||||
cookies: Cookies,
|
cookies: Cookies,
|
||||||
headers: HyperHeaders, // This sucks.
|
headers: HyperHeaders, // This sucks.
|
||||||
/// Indexes into the URI.
|
_phantom: Option<&'a str>,
|
||||||
// params: RefCell<Vec<(usize, usize)>>,
|
|
||||||
params: RefCell<Option<Vec<&'a str>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Request<'a> {
|
impl<'a> Request<'a> {
|
||||||
|
@ -58,13 +57,13 @@ impl<'a> Request<'a> {
|
||||||
/// let my_param: T = request.get_param(n);
|
/// let my_param: T = request.get_param(n);
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn get_param<T: FromParam<'a>>(&self, n: usize) -> Result<T, Error> {
|
pub fn get_param<'r, T: FromParam<'r>>(&'r self, n: usize) -> Result<T, Error> {
|
||||||
let params = self.params.borrow();
|
let params = self.params.borrow();
|
||||||
if params.is_none() || n >= params.as_ref().unwrap().len() {
|
if n >= params.len() {
|
||||||
debug!("{} is >= param count {}", n, params.as_ref().unwrap().len());
|
debug!("{} is >= param count {}", n, params.len());
|
||||||
Err(Error::NoKey)
|
Err(Error::NoKey)
|
||||||
} else {
|
} else {
|
||||||
T::from_param(params.as_ref().unwrap()[n]).map_err(|_| Error::BadParse)
|
T::from_param(params[n]).map_err(|_| Error::BadParse)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,12 +100,13 @@ impl<'a> Request<'a> {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn mock(method: Method, uri: &str) -> Request {
|
pub fn mock(method: Method, uri: &str) -> Request {
|
||||||
Request {
|
Request {
|
||||||
params: RefCell::new(None),
|
params: RefCell::new(vec![]),
|
||||||
method: method,
|
method: method,
|
||||||
cookies: Cookies::new(&[]),
|
cookies: Cookies::new(&[]),
|
||||||
uri: URIBuf::from(uri),
|
uri: URIBuf::from(uri),
|
||||||
data: vec![],
|
data: vec![],
|
||||||
headers: HyperHeaders::new(),
|
headers: HyperHeaders::new(),
|
||||||
|
_phantom: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,10 +160,18 @@ impl<'a> Request<'a> {
|
||||||
self.uri.as_uri()
|
self.uri.as_uri()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Don't need a refcell for this.
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn set_params(&'a self, route: &Route) {
|
pub fn set_params(&self, route: &Route) {
|
||||||
*self.params.borrow_mut() = Some(route.get_params(self.uri.as_uri()))
|
// We use transmute to cast the lifetime of self.uri.as_uri() to
|
||||||
|
// 'static. This is because that lifetime refers to the String in URIBuf
|
||||||
|
// in this structure, which is (obviously) guaranteed to live as long as
|
||||||
|
// the structure AS LONG AS it is not moved out or changed. AS A RESULT,
|
||||||
|
// the `uri` fields MUST NEVER be changed once it is set.
|
||||||
|
// TODO: Find a way to enforce these. Look at OwningRef for inspiration.
|
||||||
|
use ::std::mem::transmute;
|
||||||
|
*self.params.borrow_mut() = unsafe {
|
||||||
|
transmute(route.get_params(self.uri.as_uri()))
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
|
@ -200,12 +208,13 @@ impl<'a> Request<'a> {
|
||||||
h_body.read_to_end(&mut data).unwrap();
|
h_body.read_to_end(&mut data).unwrap();
|
||||||
|
|
||||||
let request = Request {
|
let request = Request {
|
||||||
params: RefCell::new(None),
|
params: RefCell::new(vec![]),
|
||||||
method: method,
|
method: method,
|
||||||
cookies: cookies,
|
cookies: cookies,
|
||||||
uri: uri,
|
uri: uri,
|
||||||
data: data,
|
data: data,
|
||||||
headers: h_headers,
|
headers: h_headers,
|
||||||
|
_phantom: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(request)
|
Ok(request)
|
||||||
|
|
Loading…
Reference in New Issue