Skip to content

Commit

Permalink
Merge pull request #755 from mayjs/upload-mediatypes
Browse files Browse the repository at this point in the history
Allow to set the accept input attribute to arbitrary values
  • Loading branch information
svenstaro authored Mar 15, 2022
2 parents d423941 + 8e37888 commit e23bcd4
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 2 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ Sometimes this is just a more practical and quick way than doing things properly

(where `$FILE` is the path to the file. This uses miniserve's default port of 8080)

### Take pictures and upload them from smartphones:

miniserve -u -m image -q

This uses the `--media-type` option, which sends a hint for the expected media type to the browser.
Some mobile browsers like Firefox on Android will offer to open the camera app when seeing this.

## Features

- Easy to use
Expand Down
20 changes: 20 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ use crate::auth;
use crate::errors::ContextualError;
use crate::renderer;

#[derive(clap::ArgEnum, Clone)]
pub enum MediaType {
Image,
Audio,
Video,
}

#[derive(Parser)]
#[clap(name = "miniserve", author, about, version)]
pub struct CliArgs {
Expand Down Expand Up @@ -104,6 +111,19 @@ pub struct CliArgs {
#[clap(short = 'u', long = "upload-files")]
pub file_upload: bool,

/// Specify uploadable media types
#[clap(arg_enum, short = 'm', long = "media-type", requires = "file-upload")]
pub media_type: Option<Vec<MediaType>>,

/// Directly specify the uploadable media type expression
#[clap(
short = 'M',
long = "raw-media-type",
requires = "file-upload",
conflicts_with = "media-type"
)]
pub media_type_raw: Option<String>,

/// Enable overriding existing files during file upload
#[clap(short = 'o', long = "overwrite-files")]
pub overwrite_files: bool,
Expand Down
23 changes: 22 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ use http::HeaderMap;
#[cfg(feature = "tls")]
use rustls_pemfile as pemfile;

use crate::{args::CliArgs, auth::RequiredAuth};
use crate::{
args::{CliArgs, MediaType},
auth::RequiredAuth,
};

/// Possible characters for random routes
const ROUTE_ALPHABET: [char; 16] = [
Expand Down Expand Up @@ -81,6 +84,9 @@ pub struct MiniserveConfig {
/// Enable file upload
pub file_upload: bool,

/// HTML accept attribute value
pub uploadable_media_type: Option<String>,

/// Enable upload to override existing files
pub overwrite_files: bool,

Expand Down Expand Up @@ -187,6 +193,20 @@ impl MiniserveConfig {
#[cfg(not(feature = "tls"))]
let tls_rustls_server_config = None;

let uploadable_media_type = args.media_type_raw.or_else(|| {
args.media_type.map(|types| {
types
.into_iter()
.map(|t| match t {
MediaType::Audio => "audio/*",
MediaType::Image => "image/*",
MediaType::Video => "video/*",
})
.collect::<Vec<_>>()
.join(",")
})
});

Ok(MiniserveConfig {
verbose: args.verbose,
path: args.path.unwrap_or_else(|| PathBuf::from(".")),
Expand All @@ -206,6 +226,7 @@ impl MiniserveConfig {
overwrite_files: args.overwrite_files,
show_qrcode: args.qrcode,
file_upload: args.file_upload,
uploadable_media_type,
tar_enabled: args.enable_tar,
tar_gz_enabled: args.enable_tar_gz,
zip_enabled: args.enable_zip,
Expand Down
5 changes: 4 additions & 1 deletion src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,10 @@ pub fn page(
form id="file_submit" action=(upload_action) method="POST" enctype="multipart/form-data" {
p { "Select a file to upload or drag it anywhere into the window" }
div {
input #file-input type="file" name="file_to_upload" required="" multiple {}
@match &conf.uploadable_media_type {
Some(accept) => {input #file-input accept=(accept) type="file" name="file_to_upload" required="" multiple {}},
None => {input #file-input type="file" name="file_to_upload" required="" multiple {}}
}
button type="submit" { "Upload file" }
}
}
Expand Down
20 changes: 20 additions & 0 deletions tests/upload_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,23 @@ fn upload_to_symlink_directory(

Ok(())
}

/// Test setting the HTML accept attribute using -m and -M.
#[rstest]
#[case(server(&["-u"]), None)]
#[case(server(&["-u", "-m", "image"]), Some("image/*"))]
#[case(server(&["-u", "-m", "image", "-m", "audio", "-m", "video"]), Some("image/*,audio/*,video/*"))]
#[case(server(&["-u", "-m", "audio", "-m", "image", "-m", "video"]), Some("audio/*,image/*,video/*"))]
#[case(server(&["-u", "-M", "test_value"]), Some("test_value"))]
fn set_media_type(
#[case] server: TestServer,
#[case] expected_accept_value: Option<&str>,
) -> Result<(), Error> {
let body = reqwest::blocking::get(server.url())?.error_for_status()?;
let parsed = Document::from_read(body)?;

let input = parsed.find(Attr("id", "file-input")).next().unwrap();
assert_eq!(input.attr("accept"), expected_accept_value);

Ok(())
}

0 comments on commit e23bcd4

Please sign in to comment.