mirror of
https://github.com/YGGverse/ggemini.git
synced 2026-03-31 09:05:45 +00:00
hold raw header string
This commit is contained in:
parent
af8a972cca
commit
5bb52fbd8c
7 changed files with 155 additions and 37 deletions
|
|
@ -9,11 +9,20 @@ const NOT_VALID: (u8, &str) = (11, "Certificate not valid");
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates
|
||||||
pub enum Certificate {
|
pub enum Certificate {
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-60
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-60
|
||||||
Required { message: Option<String> },
|
Required {
|
||||||
|
header: String,
|
||||||
|
message: Option<String>,
|
||||||
|
},
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-61-certificate-not-authorized
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-61-certificate-not-authorized
|
||||||
NotAuthorized { message: Option<String> },
|
NotAuthorized {
|
||||||
|
header: String,
|
||||||
|
message: Option<String>,
|
||||||
|
},
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-62-certificate-not-valid
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-62-certificate-not-valid
|
||||||
NotValid { message: Option<String> },
|
NotValid {
|
||||||
|
header: String,
|
||||||
|
message: Option<String>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Certificate {
|
impl Certificate {
|
||||||
|
|
@ -39,11 +48,20 @@ impl Certificate {
|
||||||
.0
|
.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn header(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Self::Required { header, .. }
|
||||||
|
| Self::NotAuthorized { header, .. }
|
||||||
|
| Self::NotValid { header, .. } => header,
|
||||||
|
}
|
||||||
|
.as_str()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn message(&self) -> Option<&str> {
|
pub fn message(&self) -> Option<&str> {
|
||||||
match self {
|
match self {
|
||||||
Self::Required { message } => message,
|
Self::Required { message, .. }
|
||||||
Self::NotAuthorized { message } => message,
|
| Self::NotAuthorized { message, .. }
|
||||||
Self::NotValid { message } => message,
|
| Self::NotValid { message, .. } => message,
|
||||||
}
|
}
|
||||||
.as_deref()
|
.as_deref()
|
||||||
}
|
}
|
||||||
|
|
@ -69,16 +87,19 @@ impl std::str::FromStr for Certificate {
|
||||||
fn from_str(header: &str) -> Result<Self, Self::Err> {
|
fn from_str(header: &str) -> Result<Self, Self::Err> {
|
||||||
if let Some(postfix) = header.strip_prefix("60") {
|
if let Some(postfix) = header.strip_prefix("60") {
|
||||||
return Ok(Self::Required {
|
return Ok(Self::Required {
|
||||||
|
header: header.to_string(),
|
||||||
message: message(postfix),
|
message: message(postfix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(postfix) = header.strip_prefix("61") {
|
if let Some(postfix) = header.strip_prefix("61") {
|
||||||
return Ok(Self::NotAuthorized {
|
return Ok(Self::NotAuthorized {
|
||||||
|
header: header.to_string(),
|
||||||
message: message(postfix),
|
message: message(postfix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(postfix) = header.strip_prefix("62") {
|
if let Some(postfix) = header.strip_prefix("62") {
|
||||||
return Ok(Self::NotValid {
|
return Ok(Self::NotValid {
|
||||||
|
header: header.to_string(),
|
||||||
message: message(postfix),
|
message: message(postfix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,13 @@ impl Failure {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn header(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Self::Permanent(permanent) => permanent.header(),
|
||||||
|
Self::Temporary(temporary) => temporary.header(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn message(&self) -> Option<&str> {
|
pub fn message(&self) -> Option<&str> {
|
||||||
match self {
|
match self {
|
||||||
Self::Permanent(permanent) => permanent.message(),
|
Self::Permanent(permanent) => permanent.message(),
|
||||||
|
|
|
||||||
|
|
@ -10,15 +10,30 @@ const BAD_REQUEST: (u8, &str) = (59, "bad-request");
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#permanent-failure
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#permanent-failure
|
||||||
pub enum Permanent {
|
pub enum Permanent {
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-50
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-50
|
||||||
Default { message: Option<String> },
|
Default {
|
||||||
|
header: String,
|
||||||
|
message: Option<String>,
|
||||||
|
},
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-51-not-found
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-51-not-found
|
||||||
NotFound { message: Option<String> },
|
NotFound {
|
||||||
|
header: String,
|
||||||
|
message: Option<String>,
|
||||||
|
},
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-52-gone
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-52-gone
|
||||||
Gone { message: Option<String> },
|
Gone {
|
||||||
|
header: String,
|
||||||
|
message: Option<String>,
|
||||||
|
},
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-53-proxy-request-refused
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-53-proxy-request-refused
|
||||||
ProxyRequestRefused { message: Option<String> },
|
ProxyRequestRefused {
|
||||||
|
header: String,
|
||||||
|
message: Option<String>,
|
||||||
|
},
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-59-bad-request
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-59-bad-request
|
||||||
BadRequest { message: Option<String> },
|
BadRequest {
|
||||||
|
header: String,
|
||||||
|
message: Option<String>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Permanent {
|
impl Permanent {
|
||||||
|
|
@ -46,13 +61,24 @@ impl Permanent {
|
||||||
.0
|
.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn header(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Self::Default { header, .. }
|
||||||
|
| Self::NotFound { header, .. }
|
||||||
|
| Self::Gone { header, .. }
|
||||||
|
| Self::ProxyRequestRefused { header, .. }
|
||||||
|
| Self::BadRequest { header, .. } => header,
|
||||||
|
}
|
||||||
|
.as_str()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn message(&self) -> Option<&str> {
|
pub fn message(&self) -> Option<&str> {
|
||||||
match self {
|
match self {
|
||||||
Self::Default { message } => message,
|
Self::Default { message, .. }
|
||||||
Self::NotFound { message } => message,
|
| Self::NotFound { message, .. }
|
||||||
Self::Gone { message } => message,
|
| Self::Gone { message, .. }
|
||||||
Self::ProxyRequestRefused { message } => message,
|
| Self::ProxyRequestRefused { message, .. }
|
||||||
Self::BadRequest { message } => message,
|
| Self::BadRequest { message, .. } => message,
|
||||||
}
|
}
|
||||||
.as_deref()
|
.as_deref()
|
||||||
}
|
}
|
||||||
|
|
@ -80,26 +106,31 @@ impl std::str::FromStr for Permanent {
|
||||||
fn from_str(header: &str) -> Result<Self, Self::Err> {
|
fn from_str(header: &str) -> Result<Self, Self::Err> {
|
||||||
if let Some(postfix) = header.strip_prefix("50") {
|
if let Some(postfix) = header.strip_prefix("50") {
|
||||||
return Ok(Self::Default {
|
return Ok(Self::Default {
|
||||||
|
header: header.to_string(),
|
||||||
message: message(postfix),
|
message: message(postfix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(postfix) = header.strip_prefix("51") {
|
if let Some(postfix) = header.strip_prefix("51") {
|
||||||
return Ok(Self::NotFound {
|
return Ok(Self::NotFound {
|
||||||
|
header: header.to_string(),
|
||||||
message: message(postfix),
|
message: message(postfix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(postfix) = header.strip_prefix("52") {
|
if let Some(postfix) = header.strip_prefix("52") {
|
||||||
return Ok(Self::Gone {
|
return Ok(Self::Gone {
|
||||||
|
header: header.to_string(),
|
||||||
message: message(postfix),
|
message: message(postfix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(postfix) = header.strip_prefix("53") {
|
if let Some(postfix) = header.strip_prefix("53") {
|
||||||
return Ok(Self::ProxyRequestRefused {
|
return Ok(Self::ProxyRequestRefused {
|
||||||
|
header: header.to_string(),
|
||||||
message: message(postfix),
|
message: message(postfix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(postfix) = header.strip_prefix("59") {
|
if let Some(postfix) = header.strip_prefix("59") {
|
||||||
return Ok(Self::BadRequest {
|
return Ok(Self::BadRequest {
|
||||||
|
header: header.to_string(),
|
||||||
message: message(postfix),
|
message: message(postfix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,15 +10,30 @@ const SLOW_DOWN: (u8, &str) = (44, "Slow down");
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#temporary-failure
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#temporary-failure
|
||||||
pub enum Temporary {
|
pub enum Temporary {
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-40
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-40
|
||||||
Default { message: Option<String> },
|
Default {
|
||||||
|
header: String,
|
||||||
|
message: Option<String>,
|
||||||
|
},
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-41-server-unavailable
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-41-server-unavailable
|
||||||
ServerUnavailable { message: Option<String> },
|
ServerUnavailable {
|
||||||
|
header: String,
|
||||||
|
message: Option<String>,
|
||||||
|
},
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-42-cgi-error
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-42-cgi-error
|
||||||
CgiError { message: Option<String> },
|
CgiError {
|
||||||
|
header: String,
|
||||||
|
message: Option<String>,
|
||||||
|
},
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-43-proxy-error
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-43-proxy-error
|
||||||
ProxyError { message: Option<String> },
|
ProxyError {
|
||||||
|
header: String,
|
||||||
|
message: Option<String>,
|
||||||
|
},
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-44-slow-down
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-44-slow-down
|
||||||
SlowDown { message: Option<String> },
|
SlowDown {
|
||||||
|
header: String,
|
||||||
|
message: Option<String>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Temporary {
|
impl Temporary {
|
||||||
|
|
@ -46,13 +61,24 @@ impl Temporary {
|
||||||
.0
|
.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn header(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Self::Default { header, .. }
|
||||||
|
| Self::ServerUnavailable { header, .. }
|
||||||
|
| Self::CgiError { header, .. }
|
||||||
|
| Self::ProxyError { header, .. }
|
||||||
|
| Self::SlowDown { header, .. } => header,
|
||||||
|
}
|
||||||
|
.as_str()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn message(&self) -> Option<&str> {
|
pub fn message(&self) -> Option<&str> {
|
||||||
match self {
|
match self {
|
||||||
Self::Default { message } => message,
|
Self::Default { message, .. }
|
||||||
Self::ServerUnavailable { message } => message,
|
| Self::ServerUnavailable { message, .. }
|
||||||
Self::CgiError { message } => message,
|
| Self::CgiError { message, .. }
|
||||||
Self::ProxyError { message } => message,
|
| Self::ProxyError { message, .. }
|
||||||
Self::SlowDown { message } => message,
|
| Self::SlowDown { message, .. } => message,
|
||||||
}
|
}
|
||||||
.as_deref()
|
.as_deref()
|
||||||
}
|
}
|
||||||
|
|
@ -80,26 +106,31 @@ impl std::str::FromStr for Temporary {
|
||||||
fn from_str(header: &str) -> Result<Self, Self::Err> {
|
fn from_str(header: &str) -> Result<Self, Self::Err> {
|
||||||
if let Some(postfix) = header.strip_prefix("40") {
|
if let Some(postfix) = header.strip_prefix("40") {
|
||||||
return Ok(Self::Default {
|
return Ok(Self::Default {
|
||||||
|
header: header.to_string(),
|
||||||
message: message(postfix),
|
message: message(postfix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(postfix) = header.strip_prefix("41") {
|
if let Some(postfix) = header.strip_prefix("41") {
|
||||||
return Ok(Self::ServerUnavailable {
|
return Ok(Self::ServerUnavailable {
|
||||||
|
header: header.to_string(),
|
||||||
message: message(postfix),
|
message: message(postfix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(postfix) = header.strip_prefix("42") {
|
if let Some(postfix) = header.strip_prefix("42") {
|
||||||
return Ok(Self::CgiError {
|
return Ok(Self::CgiError {
|
||||||
|
header: header.to_string(),
|
||||||
message: message(postfix),
|
message: message(postfix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(postfix) = header.strip_prefix("43") {
|
if let Some(postfix) = header.strip_prefix("43") {
|
||||||
return Ok(Self::ProxyError {
|
return Ok(Self::ProxyError {
|
||||||
|
header: header.to_string(),
|
||||||
message: message(postfix),
|
message: message(postfix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(postfix) = header.strip_prefix("44") {
|
if let Some(postfix) = header.strip_prefix("44") {
|
||||||
return Ok(Self::SlowDown {
|
return Ok(Self::SlowDown {
|
||||||
|
header: header.to_string(),
|
||||||
message: message(postfix),
|
message: message(postfix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,14 @@ const DEFAULT: (u8, &str) = (10, "Input");
|
||||||
const SENSITIVE: (u8, &str) = (11, "Sensitive input");
|
const SENSITIVE: (u8, &str) = (11, "Sensitive input");
|
||||||
|
|
||||||
pub enum Input {
|
pub enum Input {
|
||||||
Default { message: Option<String> },
|
Default {
|
||||||
Sensitive { message: Option<String> },
|
header: String,
|
||||||
|
message: Option<String>,
|
||||||
|
},
|
||||||
|
Sensitive {
|
||||||
|
header: String,
|
||||||
|
message: Option<String>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Input {
|
impl Input {
|
||||||
|
|
@ -31,10 +37,16 @@ impl Input {
|
||||||
.0
|
.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn header(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Self::Default { header, .. } | Self::Sensitive { header, .. } => header,
|
||||||
|
}
|
||||||
|
.as_str()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn message(&self) -> Option<&str> {
|
pub fn message(&self) -> Option<&str> {
|
||||||
match self {
|
match self {
|
||||||
Self::Default { message } => message,
|
Self::Default { message, .. } | Self::Sensitive { message, .. } => message,
|
||||||
Self::Sensitive { message } => message,
|
|
||||||
}
|
}
|
||||||
.as_deref()
|
.as_deref()
|
||||||
}
|
}
|
||||||
|
|
@ -59,11 +71,13 @@ impl std::str::FromStr for Input {
|
||||||
fn from_str(header: &str) -> Result<Self, Self::Err> {
|
fn from_str(header: &str) -> Result<Self, Self::Err> {
|
||||||
if let Some(postfix) = header.strip_prefix("10") {
|
if let Some(postfix) = header.strip_prefix("10") {
|
||||||
return Ok(Self::Default {
|
return Ok(Self::Default {
|
||||||
|
header: header.to_string(),
|
||||||
message: message(postfix),
|
message: message(postfix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(postfix) = header.strip_prefix("11") {
|
if let Some(postfix) = header.strip_prefix("11") {
|
||||||
return Ok(Self::Sensitive {
|
return Ok(Self::Sensitive {
|
||||||
|
header: header.to_string(),
|
||||||
message: message(postfix),
|
message: message(postfix),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ const PERMANENT: (u8, &str) = (31, "Permanent redirect");
|
||||||
|
|
||||||
pub enum Redirect {
|
pub enum Redirect {
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-30-temporary-redirection
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-30-temporary-redirection
|
||||||
Temporary { target: String },
|
Temporary { header: String, target: String },
|
||||||
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-31-permanent-redirection
|
/// https://geminiprotocol.net/docs/protocol-specification.gmi#status-31-permanent-redirection
|
||||||
Permanent { target: String },
|
Permanent { header: String, target: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Redirect {
|
impl Redirect {
|
||||||
|
|
@ -87,10 +87,15 @@ impl Redirect {
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
|
|
||||||
|
pub fn header(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Self::Permanent { header, .. } | Self::Temporary { header, .. } => header,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn target(&self) -> &str {
|
pub fn target(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
Self::Permanent { target } => target,
|
Self::Permanent { target, .. } | Self::Temporary { target, .. } => target,
|
||||||
Self::Temporary { target } => target,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -124,9 +129,11 @@ impl std::str::FromStr for Redirect {
|
||||||
match regex.get(1) {
|
match regex.get(1) {
|
||||||
Some(code) => match code.as_str() {
|
Some(code) => match code.as_str() {
|
||||||
"0" => Ok(Self::Temporary {
|
"0" => Ok(Self::Temporary {
|
||||||
|
header: header.to_string(),
|
||||||
target: target(regex.get(2))?,
|
target: target(regex.get(2))?,
|
||||||
}),
|
}),
|
||||||
"1" => Ok(Self::Permanent {
|
"1" => Ok(Self::Permanent {
|
||||||
|
header: header.to_string(),
|
||||||
target: target(regex.get(2))?,
|
target: target(regex.get(2))?,
|
||||||
}),
|
}),
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ pub use error::Error;
|
||||||
const DEFAULT: (u8, &str) = (20, "Success");
|
const DEFAULT: (u8, &str) = (20, "Success");
|
||||||
|
|
||||||
pub enum Success {
|
pub enum Success {
|
||||||
Default { mime: String },
|
Default { header: String, mime: String },
|
||||||
// reserved for 2* codes
|
// reserved for 2* codes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,9 +30,16 @@ impl Success {
|
||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
|
|
||||||
|
pub fn header(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Self::Default { header, .. } => header,
|
||||||
|
}
|
||||||
|
.as_str()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn mime(&self) -> &str {
|
pub fn mime(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
Self::Default { mime } => mime,
|
Self::Default { mime, .. } => mime,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -53,7 +60,6 @@ impl std::str::FromStr for Success {
|
||||||
type Err = Error;
|
type Err = Error;
|
||||||
fn from_str(header: &str) -> Result<Self, Self::Err> {
|
fn from_str(header: &str) -> Result<Self, Self::Err> {
|
||||||
use glib::{Regex, RegexCompileFlags, RegexMatchFlags};
|
use glib::{Regex, RegexCompileFlags, RegexMatchFlags};
|
||||||
|
|
||||||
match Regex::split_simple(
|
match Regex::split_simple(
|
||||||
r"^20\s([^\/]+\/[^\s;]+)",
|
r"^20\s([^\/]+\/[^\s;]+)",
|
||||||
header,
|
header,
|
||||||
|
|
@ -68,6 +74,7 @@ impl std::str::FromStr for Success {
|
||||||
Err(Error::Mime)
|
Err(Error::Mime)
|
||||||
} else {
|
} else {
|
||||||
Ok(Self::Default {
|
Ok(Self::Default {
|
||||||
|
header: header.to_string(),
|
||||||
mime: mime.to_lowercase(),
|
mime: mime.to_lowercase(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue