-
Notifications
You must be signed in to change notification settings - Fork 3
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
Embed Studio artifacts into fpx cli #48
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
6e64a00
Intermediate
hatchan 44f5f23
Rather simple and naive file hosting for Studio
hatchan 0644e60
Allow unused fn
hatchan 02fe4f5
No need to parse the file as utf8, just send the content as-is
hatchan de5ffb6
Add some simple tracing
hatchan 4886bf0
Add feature flag to embed studio
hatchan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,13 +2,14 @@ use crate::data::Store; | |
use crate::events::ServerEvents; | ||
use crate::inspector::InspectorService; | ||
use axum::extract::FromRef; | ||
use axum::response::Html; | ||
use axum::routing::{any, get}; | ||
use http::StatusCode; | ||
use url::Url; | ||
|
||
pub mod client; | ||
mod errors; | ||
pub mod handlers; | ||
mod studio; | ||
mod ws; | ||
|
||
#[derive(Clone)] | ||
|
@@ -41,7 +42,19 @@ impl FromRef<ApiState> for InspectorService { | |
} | ||
|
||
/// Create a API and expose it through a axum router. | ||
pub async fn create_api( | ||
pub fn create_api( | ||
base_url: url::Url, | ||
events: ServerEvents, | ||
store: Store, | ||
inspector_service: InspectorService, | ||
) -> axum::Router { | ||
let api_router = api_router(base_url, events, store, inspector_service); | ||
axum::Router::new() | ||
.nest("/api/", api_router) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is now split into its own router, since that way we can have separate fallback handlers. The only downside is that the routes in the inner router do not have the |
||
.fallback(studio::default_handler) | ||
} | ||
|
||
fn api_router( | ||
base_url: url::Url, | ||
events: ServerEvents, | ||
store: Store, | ||
|
@@ -53,20 +66,19 @@ pub async fn create_api( | |
store, | ||
inspector_service, | ||
}; | ||
|
||
axum::Router::new() | ||
.route( | ||
"/api/requests/:id", | ||
"/requests/:id", | ||
get(handlers::request_get_handler).delete(handlers::request_delete_handler), | ||
) | ||
.route( | ||
"/api/inspectors", | ||
"/inspectors", | ||
get(handlers::inspector_list_handler).post(handlers::inspector_create_handler), | ||
) | ||
.route("/api/inspect", any(handlers::inspect_request_handler)) | ||
.route("/api/inspect/:id", any(handlers::inspect_request_handler)) | ||
.route("/api/v1/logs", get(handlers::logs_handler)) | ||
.route("/api/ws", get(ws::ws_handler)) | ||
.route("/", get(|| async { Html("Hello, world!") })) | ||
.route("/inspect", any(handlers::inspect_request_handler)) | ||
.route("/inspect/:id", any(handlers::inspect_request_handler)) | ||
.route("/v1/logs", get(handlers::logs_handler)) | ||
.route("/ws", get(ws::ws_handler)) | ||
.fallback(StatusCode::NOT_FOUND) | ||
.with_state(api_state) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Allow unused imports since this will make it easier to work with the | ||
// different features. | ||
#![allow(unused_imports)] | ||
|
||
use axum::extract::Request; | ||
use axum::response::IntoResponse; | ||
use http::StatusCode; | ||
|
||
#[cfg(feature = "embed-studio")] | ||
static STUDIO_DIST: include_dir::Dir<'_> = | ||
include_dir::include_dir!("$CARGO_MANIFEST_DIR/../frontend/dist"); | ||
|
||
/// A simple handler that serves the frontend Studio from STUDIO_DIST. | ||
#[cfg(feature = "embed-studio")] | ||
pub async fn default_handler(req: Request) -> impl IntoResponse { | ||
tracing::trace!(uri=?req.uri(), "Serving file from embedded Studio"); | ||
|
||
let path = req.uri().path().trim_start_matches('/'); | ||
|
||
// Retrieve the File that according to the path. If it is a directory, see | ||
// if there is an index.html file. Otherwise, always fallback to the | ||
// index.html in the root. | ||
let file = STUDIO_DIST | ||
.get_entry(path) | ||
.and_then(|entry| match entry { | ||
include_dir::DirEntry::Dir(dir_entry) => { | ||
dir_entry.get_file(dir_entry.path().join("index.html")) | ||
} | ||
include_dir::DirEntry::File(file_entry) => Some(file_entry), | ||
}) | ||
.or_else(|| STUDIO_DIST.get_file("index.html")); | ||
|
||
// If nothing matches _at all_, then return a 404. | ||
let Some(file) = file else { | ||
return StatusCode::NOT_FOUND.into_response(); | ||
}; | ||
|
||
let content = file.contents(); | ||
|
||
// Naive content type detection | ||
let content_type = match file.path().extension().and_then(|ext| ext.to_str()) { | ||
Some("html") => "text/html", | ||
Some("css") => "text/css", | ||
Some("js") => "text/javascript", | ||
Some("ico") => "image/x-icon", | ||
_ => "text/plain", | ||
}; | ||
|
||
( | ||
StatusCode::OK, | ||
[(http::header::CONTENT_TYPE, content_type)], | ||
content, | ||
) | ||
.into_response() | ||
} | ||
|
||
/// The default handler when the feature `embed-studio` is not enabled. | ||
/// | ||
/// For now this will simply return a 404. | ||
#[cfg(not(feature = "embed-studio"))] | ||
pub async fn default_handler() -> impl IntoResponse { | ||
StatusCode::NOT_FOUND.into_response() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why this was async, so removed it