@@ -32,7 +32,7 @@ pub struct ServerRequest {
32
32
}
33
33
34
34
impl ServerRequest {
35
- /// Creates a new `RequestWithID ` object from an existing `Request`,
35
+ /// Creates a new `ServerRequest ` object from an existing `Request`,
36
36
/// adding an identification token.
37
37
pub fn new ( request : Request , id : u64 ) -> Self {
38
38
ServerRequest { request, id }
@@ -43,7 +43,10 @@ impl ServerRequest {
43
43
& self . request
44
44
}
45
45
46
- /// Docs needed.
46
+ /// Calls the function provided on the inner request to obtain the response.
47
+ /// The response is then wrapped in a `ServerResponse`.
48
+ ///
49
+ /// Returns a `ServerResponse` ready for yielding to the server
47
50
pub fn process < F > ( & self , callable : F ) -> ServerResponse
48
51
where
49
52
F : Fn ( & Request ) -> Response ,
@@ -246,6 +249,12 @@ pub struct HttpServer {
246
249
247
250
impl HttpServer {
248
251
/// Constructor for `HttpServer`.
252
+ ///
253
+ /// Returns the newly formed `HttpServer`.
254
+ ///
255
+ /// # Errors
256
+ /// Returns an `IOError` when binding or `epoll::create` fails.
257
+ ///
249
258
pub fn new < P : AsRef < Path > > ( path_to_socket : P ) -> Result < Self > {
250
259
let socket = UnixListener :: bind ( path_to_socket) . map_err ( ServerError :: IOError ) ?;
251
260
let epoll_fd = epoll:: create ( true ) . map_err ( ServerError :: IOError ) ?;
@@ -273,6 +282,13 @@ impl HttpServer {
273
282
///
274
283
/// Returns a collection of complete and valid requests to be processed by the user
275
284
/// of the server. Once processed, responses should be sent using `enqueue_responses()`.
285
+ ///
286
+ /// # Errors
287
+ /// `IOError` is returned when `read`, `write` or `epoll::ctl` operations fail.
288
+ /// `ServerFull` is returned when a client is trying to connect to the server, but
289
+ /// full capacity has already been reached.
290
+ /// `InvalidWrite` is returned when the server attempted to perform a write operation
291
+ /// on a connection on which it is not possible.
276
292
pub fn incoming ( & mut self ) -> Result < Vec < ServerRequest > > {
277
293
let mut parsed_requests: Vec < ServerRequest > = vec ! [ ] ;
278
294
let mut events = vec ! [ epoll:: Event :: new( epoll:: Events :: empty( ) , 0 ) ; MAX_CONNECTIONS ] ;
@@ -353,12 +369,69 @@ impl HttpServer {
353
369
Ok ( parsed_requests)
354
370
}
355
371
372
+ /// The file descriptor of the `epoll` structure can enable the server to become
373
+ /// a non-blocking structure in an application.
374
+ ///
356
375
/// Returns the file descriptor of the server's internal `epoll` structure.
376
+ ///
377
+ /// # Example
378
+ ///
379
+ /// ## Non-blocking server
380
+ /// ```
381
+ /// extern crate epoll;
382
+ ///
383
+ /// use micro_http::{HttpServer, Response, StatusCode};
384
+ ///
385
+ /// // Create our epoll manager.
386
+ /// let epoll_fd = epoll::create(true).unwrap();
387
+ ///
388
+ /// let path_to_socket = "/tmp/epoll_example.sock";
389
+ /// std::fs::remove_file(path_to_socket).unwrap_or_default();
390
+ ///
391
+ /// // Start the server.
392
+ /// let mut server = HttpServer::new(path_to_socket).unwrap();
393
+ /// server.start_server().unwrap();
394
+ ///
395
+ /// // Add our server to the `epoll` manager.
396
+ /// epoll::ctl(
397
+ /// epoll_fd,
398
+ /// epoll::ControlOptions::EPOLL_CTL_ADD,
399
+ /// server.epoll_fd(),
400
+ /// epoll::Event::new(epoll::Events::EPOLLIN, 1234u64),
401
+ /// ).unwrap();
402
+ ///
403
+ /// // Connect a client to the server so it doesn't block in our example.
404
+ /// let mut socket = std::os::unix::net::UnixStream::connect(path_to_socket).unwrap();
405
+ ///
406
+ /// // Control loop of the application.
407
+ /// let mut events = Vec::with_capacity(10);
408
+ /// loop {
409
+ /// let num_ev = epoll::wait(epoll_fd, -1, events.as_mut_slice());
410
+ /// for event in events {
411
+ /// match event.data {
412
+ /// // The server notification.
413
+ /// 1234 => {
414
+ /// let request = server.incoming();
415
+ /// // Process...
416
+ /// },
417
+ /// // Other `epoll` notifications.
418
+ /// _ => {
419
+ /// // Do other computation.
420
+ /// },
421
+ /// }
422
+ /// }
423
+ /// // Break this example loop.
424
+ /// break;
425
+ /// }
426
+ /// ```
357
427
pub fn epoll_fd ( & self ) -> RawFd {
358
428
self . epoll_fd
359
429
}
360
430
361
431
/// Enqueues the provided responses in the outgoing connection.
432
+ ///
433
+ /// # Errors
434
+ /// `IOError` is returned when an `epoll::ctl` operation fails.
362
435
pub fn enqueue_responses ( & mut self , responses : Vec < ServerResponse > ) -> Result < ( ) > {
363
436
for response in responses {
364
437
self . respond ( response) ?;
@@ -367,7 +440,10 @@ impl HttpServer {
367
440
Ok ( ( ) )
368
441
}
369
442
370
- /// Docs needed.
443
+ /// Adds the provided response to the outgoing buffer in the corresponding connection.
444
+ ///
445
+ /// # Errors
446
+ /// `IOError` is returned when an `epoll::ctl` operation fails.
371
447
pub fn respond ( & mut self , response : ServerResponse ) -> Result < ( ) > {
372
448
if let Some ( client_connection) = self . connections . get_mut ( & ( response. id as i32 ) ) {
373
449
// If the connection was incoming before we enqueue the response, we change its
@@ -382,6 +458,9 @@ impl HttpServer {
382
458
}
383
459
384
460
/// Accepts a new incoming connection and adds it to the `epoll` notification structure.
461
+ ///
462
+ /// # Errors
463
+ /// `IOError` is returned when an `epoll::ctl` operation fails.
385
464
fn handle_new_connection ( & mut self ) -> Result < ( ) > {
386
465
if self . connections . len ( ) == MAX_CONNECTIONS {
387
466
// If we want a replacement policy for connections
0 commit comments