Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

switch block-style to line-style comments #553

Merged
merged 3 commits into from
Jan 9, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 22 additions & 48 deletions dropshot/examples/basic.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// Copyright 2020 Oxide Computer Company
/*!
* Example use of Dropshot.
*/
//! Example use of Dropshot.

use dropshot::endpoint;
use dropshot::ApiDescription;
Expand All @@ -23,85 +21,63 @@ use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), String> {
/*
* We must specify a configuration with a bind address. We'll use 127.0.0.1
* since it's available and won't expose this server outside the host. We
* request port 0, which allows the operating system to pick any available
* port.
*/
// We must specify a configuration with a bind address. We'll use 127.0.0.1
// since it's available and won't expose this server outside the host. We
// request port 0, which allows the operating system to pick any available
// port.
let config_dropshot: ConfigDropshot = Default::default();

/*
* For simplicity, we'll configure an "info"-level logger that writes to
* stderr assuming that it's a terminal.
*/
// For simplicity, we'll configure an "info"-level logger that writes to
// stderr assuming that it's a terminal.
let config_logging =
ConfigLogging::StderrTerminal { level: ConfigLoggingLevel::Info };
let log = config_logging
.to_logger("example-basic")
.map_err(|error| format!("failed to create logger: {}", error))?;

/*
* Build a description of the API.
*/
// Build a description of the API.
let mut api = ApiDescription::new();
api.register(example_api_get_counter).unwrap();
api.register(example_api_put_counter).unwrap();

/*
* The functions that implement our API endpoints will share this context.
*/
// The functions that implement our API endpoints will share this context.
let api_context = ExampleContext::new();

/*
* Set up the server.
*/
// Set up the server.
let server =
HttpServerStarter::new(&config_dropshot, api, api_context, &log)
.map_err(|error| format!("failed to create server: {}", error))?
.start();

/*
* Wait for the server to stop. Note that there's not any code to shut down
* this server, so we should never get past this point.
*/
// Wait for the server to stop. Note that there's not any code to shut down
// this server, so we should never get past this point.
server.await
}

/**
* Application-specific example context (state shared by handler functions)
*/
/// Application-specific example context (state shared by handler functions)
struct ExampleContext {
/** counter that can be manipulated by requests to the HTTP API */
/// counter that can be manipulated by requests to the HTTP API
counter: AtomicU64,
}

impl ExampleContext {
/**
* Return a new ExampleContext.
*/
/// Return a new ExampleContext.
pub fn new() -> ExampleContext {
ExampleContext { counter: AtomicU64::new(0) }
}
}

/*
* HTTP API interface
*/
// HTTP API interface

/**
* `CounterValue` represents the value of the API's counter, either as the
* response to a GET request to fetch the counter or as the body of a PUT
* request to update the counter.
*/
/// `CounterValue` represents the value of the API's counter, either as the
/// response to a GET request to fetch the counter or as the body of a PUT
/// request to update the counter.
#[derive(Deserialize, Serialize, JsonSchema)]
struct CounterValue {
counter: u64,
}

/**
* Fetch the current value of the counter.
*/
/// Fetch the current value of the counter.
#[endpoint {
method = GET,
path = "/counter",
Expand All @@ -116,10 +92,8 @@ async fn example_api_get_counter(
}))
}

/**
* Update the current value of the counter. Note that the special value of 10
* is not allowed (just to demonstrate how to generate an error).
*/
/// Update the current value of the counter. Note that the special value of 10
/// is not allowed (just to demonstrate how to generate an error).
#[endpoint {
method = PUT,
path = "/counter",
Expand Down
98 changes: 36 additions & 62 deletions dropshot/examples/file_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,69 +16,51 @@ use serde::Deserialize;
use std::path::PathBuf;
use std::sync::Arc;

/**
* Our context is simply the root of the directory we want to serve.
*/
/// Our context is simply the root of the directory we want to serve.
struct FileServerContext {
base: PathBuf,
}

#[tokio::main]
async fn main() -> Result<(), String> {
/*
* We must specify a configuration with a bind address. We'll use 127.0.0.1
* since it's available and won't expose this server outside the host. We
* request port 0, which allows the operating system to pick any available
* port.
*/
// We must specify a configuration with a bind address. We'll use 127.0.0.1
// since it's available and won't expose this server outside the host. We
// request port 0, which allows the operating system to pick any available
// port.
let config_dropshot = Default::default();

/*
* For simplicity, we'll configure an "info"-level logger that writes to
* stderr assuming that it's a terminal.
*/
// For simplicity, we'll configure an "info"-level logger that writes to
// stderr assuming that it's a terminal.
let config_logging =
ConfigLogging::StderrTerminal { level: ConfigLoggingLevel::Info };
let log = config_logging
.to_logger("example-basic")
.map_err(|error| format!("failed to create logger: {}", error))?;

/*
* Build a description of the API -- in this case it's not much of an API!.
*/
// Build a description of the API -- in this case it's not much of an API!.
let mut api = ApiDescription::new();
api.register(static_content).unwrap();

/*
* Specify the directory we want to serve.
*/
// Specify the directory we want to serve.
let context = FileServerContext { base: PathBuf::from(".") };

/*
* Set up the server.
*/
// Set up the server.
let server = HttpServerStarter::new(&config_dropshot, api, context, &log)
.map_err(|error| format!("failed to create server: {}", error))?
.start();

/*
* Wait for the server to stop. Note that there's not any code to shut down
* this server, so we should never get past this point.
*/
// Wait for the server to stop. Note that there's not any code to shut down
// this server, so we should never get past this point.
server.await
}

/**
* Dropshot deserializes the input path into this Vec.
*/
/// Dropshot deserializes the input path into this Vec.
#[derive(Deserialize, JsonSchema)]
struct AllPath {
path: Vec<String>,
}

/**
* Serve files from the specified root path.
*/
/// Serve files from the specified root path.
#[endpoint {
method = GET,

Expand All @@ -100,25 +82,23 @@ async fn static_content(
let path = path.into_inner().path;
let mut entry = rqctx.context().base.clone();
for component in &path {
/* The previous iteration needs to have resulted in a directory. */
// The previous iteration needs to have resulted in a directory.
if !entry.is_dir() {
return Err(HttpError::for_bad_request(
None,
format!("expected directory: {:?}", entry),
));
}
/* Dropshot won't ever give us dot-components. */
// Dropshot won't ever give us dot-components.
assert_ne!(component, ".");
assert_ne!(component, "..");
entry.push(component);

/*
* We explicitly prohibit consumers from following symlinks to prevent
* showing data outside of the intended directory.
* TODO-security There's a time-of-check to time-of-use race here!
* Someone could replace "entry" with a symlink immediately after we
* check.
*/
// We explicitly prohibit consumers from following symlinks to prevent
// showing data outside of the intended directory.
// TODO-security There's a time-of-check to time-of-use race here!
// Someone could replace "entry" with a symlink immediately after we
// check.
let m = entry.symlink_metadata().map_err(|e| {
HttpError::for_bad_request(
None,
Expand All @@ -133,10 +113,8 @@ async fn static_content(
}
}

/*
* If the entry is a directory, we serve a listing of its contents. If it's
* regular file we serve the file.
*/
// If the entry is a directory, we serve a listing of its contents. If it's
// regular file we serve the file.
if entry.is_dir() {
let body = dir_body(&entry).await.map_err(|e| {
HttpError::for_bad_request(
Expand All @@ -158,7 +136,7 @@ async fn static_content(
})?;
let file_stream = hyper_staticfile::FileBytesStream::new(file);

/* Derive the MIME type from the file name */
// Derive the MIME type from the file name
let content_type = mime_guess::from_path(&entry)
.first()
.map_or_else(|| "text/plain".to_string(), |m| m.to_string());
Expand All @@ -170,10 +148,8 @@ async fn static_content(
}
}

/**
* Generate a simple HTML listing of files within the directory.
* See the note below regarding the handling of trailing slashes.
*/
/// Generate a simple HTML listing of files within the directory.
/// See the note below regarding the handling of trailing slashes.
async fn dir_body(dir_path: &PathBuf) -> Result<String, std::io::Error> {
let dir_link = dir_path.to_string_lossy();
let mut dir = tokio::fs::read_dir(&dir_path).await?;
Expand All @@ -195,18 +171,16 @@ async fn dir_body(dir_path: &PathBuf) -> Result<String, std::io::Error> {
while let Some(entry) = dir.next_entry().await? {
let name = entry.file_name();
let name = name.to_string_lossy();
/*
* Note that Dropshot handles paths with and without trailing slashes
* as identical. This is important with respect to relative paths as
* the destination of a relative path is different depending on whether
* or not a trailing slash is present in the browser's location bar.
* For example, a relative url of "bar" would go from the location
* "localhost:123/foo" to "localhost:123/bar" and from the location
* "localhost:123/foo/" to "localhost:123/foo/bar". More robust
* handling would require distinct handling of the trailing slash
* and a redirect in the case of its absence when navigating to a
* directory.
*/
// Note that Dropshot handles paths with and without trailing slashes
// as identical. This is important with respect to relative paths as
// the destination of a relative path is different depending on whether
// or not a trailing slash is present in the browser's location bar.
// For example, a relative url of "bar" would go from the location
// "localhost:123/foo" to "localhost:123/bar" and from the location
// "localhost:123/foo/" to "localhost:123/foo/bar". More robust
// handling would require distinct handling of the trailing slash
// and a redirect in the case of its absence when navigating to a
// directory.
body.push_str(
format!(
r#"<li><a href="{}{}">{}</a></li>"#,
Expand Down
Loading