Skip to content

Commit

Permalink
Allow resolving a link share without redirecting.
Browse files Browse the repository at this point in the history
Also change default password to "default", as documented.
  • Loading branch information
Artemis21 committed Sep 26, 2021
1 parent ae99154 commit c941162
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "shareit"
version = "0.3.1"
version = "0.4.0"
edition = "2018"
authors = ["Artemis <[email protected]>"]
description = "A link shortener, file uploader and paste bin."
Expand Down
11 changes: 11 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ will return the paste contents, with the `Share-Highlighting` header set.
The `Share-Type` header will also be set on the response, to one of `link`,
`file`, or `paste`.

If the `Accept-Redirect` header on the request is set to `no`, the server will
give exactly the same response, but use the `200` status code instead of `307`.
For non-link shares, it will always use `200` for successful requests.

This is to allow web frontends to resolve link shares, since browsers do not
allow scripts to get the resolved URL of an HTTP redirect (see
[the spec](https://fetch.spec.whatwg.org/#atomic-http-redirect-handling)).

### `DELETE /<name>`

Delete a share you created. This endpoint returns a `204` response if
Expand All @@ -136,6 +144,9 @@ For file and paste shares respectively, the `Content-Type` and
A password or share token should be set as described in
[**Authentication**](#authentication).

This endpoint will give the same response as the `GET /<name>` endpoint,
including handling the `Accept-Redirect` header.

### `GET /`

Returns the `index.html` file of the frontend if enabled, or a `404` error
Expand Down
5 changes: 3 additions & 2 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ pub fn get(
conn: DbConn,
conf: State<Config>,
name: String,
headers: HeaderParams,
) -> Result<ShareBodyResponder, status::Custom<String>> {
Ok(Share::get(name, &conn, &conf.upload_dir)?.body_response(conf))
Ok(Share::get(name, &conn, &conf.upload_dir)?.body_response(conf, headers.accept_redirect))
}

/// Delete a share.
Expand Down Expand Up @@ -130,7 +131,7 @@ pub fn update(
.set(&share)
.execute(&conn.0)
.map_err(|_| status::Custom(Status::InternalServerError, "Database error.".into()))?;
Ok(share.body_response(conf))
Ok(share.body_response(conf, headers.accept_redirect))
}

/// Get information on the features this server supports.
Expand Down
2 changes: 1 addition & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::sync::RwLock;
use std::time::Duration;
use std::{env, process};

pub const DEFAULT_PASSWORD: &str = "password";
pub const DEFAULT_PASSWORD: &str = "default";

fn default_highlighting_language() -> String { "auto".into() }
fn default_mime_type() -> String { "application/octet-stream".into() }
Expand Down
3 changes: 3 additions & 0 deletions src/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub struct HeaderParams {
pub mime_type: Option<String>,
expire_after: Option<Duration>,
pub content_length: Option<u64>,
pub accept_redirect: bool,
}

impl HeaderParams {
Expand Down Expand Up @@ -163,6 +164,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for HeaderParams {
let language = headers.get_one("Share-Highlighting").map(|s| s.to_string());
let mime_type = headers.get_one("Content-Type").map(|s| s.to_string());
let raw_auth = headers.get_one("Authorization").map(|s| s.to_string());
let accept_redirect = !matches!(headers.get_one("Accept-Redirect"), Some("no"));
let kind = match Self::parse_kind(headers.get_one("Share-Type")) {
Ok(kind) => kind,
Err(e) => return Outcome::Failure(e),
Expand All @@ -179,6 +181,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for HeaderParams {
mime_type,
expire_after,
content_length,
accept_redirect,
})
}
}
3 changes: 2 additions & 1 deletion src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,10 @@ impl Share {
}
}

pub fn body_response(self, conf: State<Config>) -> ShareBodyResponder {
pub fn body_response(self, conf: State<Config>, accept_redirect: bool) -> ShareBodyResponder {
ShareBodyResponder {
conf,
accept_redirect,
name: self.name,
kind: self.kind,
link: self.link,
Expand Down
11 changes: 9 additions & 2 deletions src/responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::io;

pub struct ShareBodyResponder<'a> {
pub conf: State<'a, Config>,
pub accept_redirect: bool,
pub name: String,
pub kind: ShareKind,
pub link: Option<String>,
Expand All @@ -27,9 +28,15 @@ impl<'a> ShareBodyResponder<'a> {
fn link_response(self, response: &mut ResponseBuilder) {
match self.link {
Some(link) => {
let status = if self.accept_redirect {
Status::TemporaryRedirect
} else {
Status::Ok
};
response
.status(Status::TemporaryRedirect)
.raw_header("Location", link);
.status(status)
.raw_header("Location", link.clone())
.sized_body(io::Cursor::new(link));
}
None => self.error_response(response, "Share link unexpectedly missing.".into()),
};
Expand Down

0 comments on commit c941162

Please sign in to comment.