1
1
2
2
#![ crate_name = "fcgi" ]
3
3
#![ crate_type = "lib" ]
4
+ #![ feature( cstr_memory, cstr_to_str) ]
4
5
5
6
//! This package provides a Rust binding to the C/C++ [fast-cgi library][]
6
7
//!
43
44
//! ```
44
45
45
46
extern crate libc;
46
- use std:: default:: Default ;
47
+ use std:: default:: Default ;
47
48
use std:: ffi;
48
- use std:: str;
49
-
50
-
49
+ use std:: ffi:: { CString } ;
50
+ use std:: os:: unix:: io:: { RawFd } ;
51
51
pub mod capi;
52
52
53
53
/// Initialize the FCGX library. Returns true upon success.
@@ -65,14 +65,17 @@ pub fn is_cgi() -> bool {
65
65
}
66
66
}
67
67
68
- #[ deriving ( Copy ) ]
68
+ #[ derive ( Clone , Copy ) ]
69
69
pub enum StreamType { OutStream , InStream , ErrStream }
70
70
71
71
/// Methods for working with an FCGI request object. A default implementation is provided within this package.
72
72
pub trait Request {
73
73
74
74
/// Creates a new already initialized instance of an FCGI request.
75
- fn new ( ) -> Option < Self > ;
75
+ fn new ( ) -> Option < Self > where Self : Sized ;
76
+
77
+ /// Creates a new already initialized instance of an FCGI request.
78
+ fn new_with_fd ( fd : RawFd ) -> Option < Self > where Self : Sized ;
76
79
77
80
/// Accept a new request (multi-thread safe). Be sure to call initialize_fcgi() first.
78
81
fn accept ( & mut self ) -> bool ;
@@ -121,6 +124,17 @@ impl Request for DefaultRequest {
121
124
}
122
125
}
123
126
}
127
+
128
+ fn new_with_fd ( fd : RawFd ) -> Option < DefaultRequest > {
129
+ let mut request: capi:: FCGX_Request = Default :: default ( ) ;
130
+ unsafe {
131
+ if capi:: FCGX_InitRequest ( & mut request, fd, 0 ) == 0 {
132
+ return Some ( DefaultRequest { raw_request : request } ) ;
133
+ } else {
134
+ return None ;
135
+ }
136
+ }
137
+ }
124
138
125
139
fn accept ( & mut self ) -> bool {
126
140
unsafe {
@@ -135,27 +149,28 @@ impl Request for DefaultRequest {
135
149
}
136
150
137
151
fn get_param ( & self , name : & str ) -> Option < String > {
138
- let cstr = ffi :: CString :: from_slice ( name. as_bytes ( ) ) ;
152
+ let cstr = CString :: new ( name) . unwrap ( ) ;
139
153
unsafe {
140
154
let param = capi:: FCGX_GetParam ( cstr. as_ptr ( ) , self . raw_request . envp ) ;
141
155
if param. is_null ( ) {
142
156
return None ;
143
157
}
144
- let resultStr = str:: from_c_str ( param) ;
145
- return Some ( String :: from_str ( resultStr) ) ;
158
+ let result_cstr = ffi:: CString :: from_ptr ( param) ;
159
+ let result_str = result_cstr. to_str ( ) . unwrap ( ) ;
160
+ return Some ( String :: from ( result_str) ) ;
146
161
}
147
162
}
148
163
149
164
fn write ( & mut self , msg : & str ) -> i32 {
150
- let cstr = ffi:: CString :: from_slice ( msg. as_bytes ( ) ) ;
165
+ let cstr = ffi:: CString :: new ( msg) . unwrap ( ) ;
151
166
unsafe {
152
167
return capi:: FCGX_PutS ( cstr. as_ptr ( ) , self . raw_request . out_stream ) ;
153
168
}
154
169
}
155
170
156
171
fn error ( & mut self , msg : & str ) -> i32 {
157
- let cstr = ffi:: CString :: from_slice ( msg. as_bytes ( ) ) ;
158
- unsafe {
172
+ let cstr = ffi:: CString :: new ( msg. as_bytes ( ) ) . unwrap ( ) ;
173
+ unsafe {
159
174
return capi:: FCGX_PutS ( cstr. as_ptr ( ) , self . raw_request . err_stream ) ;
160
175
}
161
176
}
@@ -167,22 +182,23 @@ impl Request for DefaultRequest {
167
182
let pdst = buffer. as_mut_ptr ( ) ;
168
183
let byte_count = capi:: FCGX_GetStr ( pdst, n, self . raw_request . in_stream ) ;
169
184
buffer. set_len ( byte_count as usize ) ;
170
- let resultStr = str:: from_c_str ( pdst) ;
171
- return ( String :: from_str ( resultStr) , byte_count) ;
185
+ let result_cstr = ffi:: CString :: from_ptr ( pdst) ;
186
+ let result_str = result_cstr. to_str ( ) . unwrap ( ) ;
187
+ return ( String :: from ( result_str) , byte_count) ;
172
188
}
173
189
}
174
190
175
191
fn readall ( & mut self ) -> String {
176
192
let ( mut msg, mut n) = self . read ( 512 ) ;
177
193
while n == 512 {
178
194
let ( new_msg, new_n) = self . read ( 512 ) ;
179
- msg = msg + new_msg. as_slice ( ) ;
195
+ msg = msg + new_msg. as_ref ( ) ;
180
196
n = new_n;
181
197
}
182
198
return msg;
183
199
}
184
200
185
- fn flush ( & mut self , stream_type : StreamType ) {
201
+ fn flush ( & mut self , stream_type : StreamType ) {
186
202
let stream = match stream_type {
187
203
StreamType :: OutStream => self . raw_request . out_stream ,
188
204
StreamType :: InStream => self . raw_request . in_stream ,
0 commit comments