1
1
use std:: fmt;
2
2
3
3
use header:: Headers ;
4
- use http:: { Body , RequestHead } ;
4
+ use http:: { Body , MessageHead , RequestHead , RequestLine } ;
5
5
use method:: Method ;
6
6
use uri:: { self , Uri } ;
7
7
use version:: HttpVersion ;
8
+ use std:: net:: SocketAddr ;
8
9
9
10
/// A client request to a remote server.
10
11
pub struct Request < B = Body > {
@@ -14,6 +15,7 @@ pub struct Request<B = Body> {
14
15
headers : Headers ,
15
16
body : Option < B > ,
16
17
is_proxy : bool ,
18
+ remote_addr : Option < SocketAddr > ,
17
19
}
18
20
19
21
impl < B > Request < B > {
@@ -27,13 +29,14 @@ impl<B> Request<B> {
27
29
headers : Headers :: new ( ) ,
28
30
body : None ,
29
31
is_proxy : false ,
32
+ remote_addr : None ,
30
33
}
31
34
}
32
35
33
36
/// Read the Request Uri.
34
37
#[ inline]
35
38
pub fn uri ( & self ) -> & Uri { & self . uri }
36
-
39
+
37
40
/// Read the Request Version.
38
41
#[ inline]
39
42
pub fn version ( & self ) -> HttpVersion { self . version }
@@ -48,8 +51,29 @@ impl<B> Request<B> {
48
51
49
52
/// Read the Request body.
50
53
#[ inline]
51
- pub fn body ( & self ) -> Option < & B > { self . body . as_ref ( ) }
52
-
54
+ pub fn body_ref ( & self ) -> Option < & B > { self . body . as_ref ( ) }
55
+
56
+ /// The remote socket address of this request
57
+ ///
58
+ /// This is an `Option`, because some underlying transports may not have
59
+ /// a socket address, such as Unix Sockets.
60
+ ///
61
+ /// This field is not used for outgoing requests.
62
+ #[ inline]
63
+ pub fn remote_addr ( & self ) -> Option < SocketAddr > { self . remote_addr }
64
+
65
+ /// The target path of this Request.
66
+ #[ inline]
67
+ pub fn path ( & self ) -> & str {
68
+ self . uri . path ( )
69
+ }
70
+
71
+ /// The query string of this Request.
72
+ #[ inline]
73
+ pub fn query ( & self ) -> Option < & str > {
74
+ self . uri . query ( )
75
+ }
76
+
53
77
/// Set the Method of this request.
54
78
#[ inline]
55
79
pub fn set_method ( & mut self , method : Method ) { self . method = method; }
@@ -78,17 +102,60 @@ impl<B> Request<B> {
78
102
pub fn set_proxy ( & mut self , is_proxy : bool ) { self . is_proxy = is_proxy; }
79
103
}
80
104
105
+ impl Request < Body > {
106
+ /// Deconstruct this Request into its pieces.
107
+ ///
108
+ /// Modifying these pieces will have no effect on how hyper behaves.
109
+ #[ inline]
110
+ pub fn deconstruct ( self ) -> ( Method , Uri , HttpVersion , Headers , Body ) {
111
+ ( self . method , self . uri , self . version , self . headers , self . body . unwrap_or_default ( ) )
112
+ }
113
+
114
+ /// Take the Request body.
115
+ #[ inline]
116
+ pub fn body ( self ) -> Body { self . body . unwrap_or_default ( ) }
117
+ }
118
+
81
119
impl < B > fmt:: Debug for Request < B > {
82
120
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
83
121
f. debug_struct ( "Request" )
84
122
. field ( "method" , & self . method )
85
123
. field ( "uri" , & self . uri )
86
124
. field ( "version" , & self . version )
125
+ . field ( "remote_addr" , & self . remote_addr )
87
126
. field ( "headers" , & self . headers )
88
127
. finish ( )
89
128
}
90
129
}
91
130
131
+ struct MaybeAddr < ' a > ( & ' a Option < SocketAddr > ) ;
132
+
133
+ impl < ' a > fmt:: Display for MaybeAddr < ' a > {
134
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
135
+ match * self . 0 {
136
+ Some ( ref addr) => fmt:: Display :: fmt ( addr, f) ,
137
+ None => f. write_str ( "None" ) ,
138
+ }
139
+ }
140
+ }
141
+
142
+ /// Constructs a request using a received ResponseHead and optional body
143
+ pub fn from_wire < B > ( addr : Option < SocketAddr > , incoming : RequestHead , body : B ) -> Request < B > {
144
+ let MessageHead { version, subject : RequestLine ( method, uri) , headers } = incoming;
145
+ debug ! ( "Request::new: addr={}, req=\" {} {} {}\" " , MaybeAddr ( & addr) , method, uri, version) ;
146
+ debug ! ( "Request::new: headers={:?}" , headers) ;
147
+
148
+ Request :: < B > {
149
+ method : method,
150
+ uri : uri,
151
+ headers : headers,
152
+ version : version,
153
+ remote_addr : addr,
154
+ body : Some ( body) ,
155
+ is_proxy : false ,
156
+ }
157
+ }
158
+
92
159
pub fn split < B > ( req : Request < B > ) -> ( RequestHead , Option < B > ) {
93
160
let uri = if req. is_proxy {
94
161
req. uri
0 commit comments