kettle11 / devserver

A simple HTTPS server for local development. Implemented in Rust.
zlib License
95 stars 15 forks source link

WIP: attempt at: Ignoring URL arguments when a file without the arguments exists #19

Closed berkes closed 2 years ago

berkes commented 3 years ago

Being new to Rust, I'm struggling to implement a solution for #18 ( Ignore URL arguments when a file without the arguments exists.)

So far, I managed to refactor the logic that reads the file a bit into the following logic:

  1. build a list of candidates for files.
  2. loop through that list, the first that can be read is the file to be served.
  3. serve that file.

But I'm stuck "fighting" the rust compiler. I am not able to store the contents of the file when read in step 2, to serve it later on.

Before I pour much more time into this, I'd like to know if this direction is acceptable at all. And if so, if you like what I did with the FileProxy struct and so. As is probably clear from my code, I'm new to Rust and come from a OOP background; the code is probably a bit too OOP?

And if this is the right direction: any hints to what I'm doing wrong structure- or logic wise would be very welcome πŸ˜„

error[E0381]: use of possibly-uninitialized variable: `file_contents`
  --> devserver_lib/src/lib.rs:77:36
   |
77 |     if let Ok(mut file_contents) = file_contents {
   |                                    ^^^^^^^^^^^^^ use of possibly-uninitialized `file_contents`
kettle11 commented 3 years ago

Thanks for looking into this!

Rust can be a bit tricky at first, but after reading through your code it looks like it's almost working!

FileProxy looks fine to me! Certainly not too object-oriented for my tastes.


error[E0381]: use of possibly-uninitialized variable: `file_contents`
  --> devserver_lib/src/lib.rs:77:36
   |
77 |     if let Ok(mut file_contents) = file_contents {
   |                                    ^^^^^^^^^^^^^ use of possibly-uninitialized `file_contents`

This error can be resolved by initializing file_contents to an std::io::Error like so:

let mut file_contents = Err(Error::new(ErrorKind::NotFound, "No matching file found"));

Which makes sense, we're initializing with an Error but if we find a matching file we replace the error with an Ok value.

I'll add more comments on the code itself.

berkes commented 3 years ago

I've implemented all your suggestions and -indeed- the missing part how to assign the file_contents works like a charm! Thanks a million for your help!

Some notes and question:

So in this case the function can be reduced to:

I'm not sure if the ::new now makes a lot of sense. I've left it in, to keep the candidates method a bit cleaner, but the benefit is not that big. Let me know if you want me to remove it.

String::from("") and String::new() do the same thing.

Eventhough I knew that both were possible, I forgot about it. Rust is not ingrained enough yet! Thanks for the reminder!

And one larger issue. Not so much with code, but about the logic:

The way I've implemented it, when you have:

β”œβ”€β”€ index.html : content: Hello World
└── mars
    └── index.html : content Hello Mars

And you request the following, you get the following:

localhost:8080/ -> Hello World
localhost:8080/index.html -> Hello World.
localhost:8080/mars/ -> Hello Mars

But when you request the following, you unexpectedly get:

localhost:8080/venus/ -> Hello World
localhost:8080/app.css -> Hello World

All due to the fallback to index.html. Which may not always be what you want. What do you think? Should all the latter return a 404? I think so, but thought I'd check first.

berkes commented 2 years ago

I guess this can be closed as it has long been fixed in f7ae298