rejig how things work so that http1 is a seperate module.
This commit is contained in:
parent
fb37ffd0e6
commit
7d5530370f
3 changed files with 234 additions and 235 deletions
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "packeteer"
|
||||
description = "An attempt at a Rust library that can be used to assist in programmatically analysing, serving and handling received protocol packets."
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
edition = "2021"
|
||||
authors = ["Celeste <colean@colean.cc>"]
|
||||
license = "LGPL-3.0-or-later"
|
||||
|
|
232
src/http1.rs
Normal file
232
src/http1.rs
Normal file
|
@ -0,0 +1,232 @@
|
|||
//! The module handling HTTP/1.0 and HTTP/1.1 operations.
|
||||
//! It contains structures for HTTP/1.x requests and responses as well as functions for generating, unpacking and constructing them.
|
||||
//! It can also upgrade and downgrade HTTP/1.x requests.
|
||||
use super::{KVHeader, generate_kvheader};
|
||||
use std::str::FromStr;
|
||||
|
||||
/// A structure for HTTP/1.x requests.
|
||||
/// Generated with packeteer::http1::generate_request.
|
||||
#[derive(Debug)]
|
||||
pub struct Http1Request {
|
||||
pub method: String,
|
||||
pub location: String,
|
||||
pub version: String,
|
||||
pub headers: Vec<KVHeader>,
|
||||
pub body: String,
|
||||
}
|
||||
/// A structure for HTTP/1.x responses.
|
||||
/// Generated with packeteer::http1::generate_response.
|
||||
#[derive(Debug)]
|
||||
pub struct Http1Response {
|
||||
pub version: String,
|
||||
pub status: String,
|
||||
pub headers: Vec<KVHeader>,
|
||||
pub body: String,
|
||||
pub code: i32,
|
||||
}
|
||||
|
||||
/// A function for generating Http1Request structures.
|
||||
/// By default, packeteer generates HTTP/1.1 requests.
|
||||
pub fn generate_request(method: &str, host: &str, location: &str, body: &str) -> Http1Request {
|
||||
let hostkv = generate_kvheader("Host", host);
|
||||
let request = Http1Request { method: method.to_string(), location: location.to_string(), version: "1.1".to_string(), headers: vec![hostkv], body: body.to_string() };
|
||||
return request
|
||||
}
|
||||
/// A function for generating Http1Response structures.
|
||||
/// By default, packeteer generates HTTP/1.1 responses.
|
||||
pub fn generate_response(code: i32, body: &str) -> Http1Response {
|
||||
let mut xcode = code;
|
||||
if code_to_string(xcode) == "500 Internal Server Error" {
|
||||
xcode = 500;
|
||||
}
|
||||
let response = Http1Response { version: "1.1".to_string(), status: code_to_string(xcode), headers: vec![], body: body.to_string(), code: xcode };
|
||||
return response
|
||||
}
|
||||
/// A function for converting HTTP/1.x request strings into Http1Request.
|
||||
/// Construction functions aim to be as transparent as possible so apart from turning it into a structure, the request stays relatively unchanged.
|
||||
pub fn construct_request(request: &str) -> Http1Request {
|
||||
let split = request.split("\r\n");
|
||||
let mut request = Http1Request { method: "".to_string(), location: "".to_string(), version: "".to_string(), headers: vec![], body: "".to_string() };
|
||||
let mut reachedbody = false;
|
||||
for v in split {
|
||||
if reachedbody != true {
|
||||
if v.contains("HTTP/1.1") {
|
||||
let split1: Vec<&str> = v.split(" ").collect();
|
||||
request.method = split1[0].to_string();
|
||||
request.location = split1[1].to_string();
|
||||
request.version = "1.1".to_string();
|
||||
} else if v.contains("HTTP/1.0") {
|
||||
let split1: Vec<&str> = v.split(" ").collect();
|
||||
request.method = split1[0].to_string();
|
||||
request.location = split1[1].to_string();
|
||||
request.version = "1.0".to_string();
|
||||
} else if v == "" {
|
||||
reachedbody = true;
|
||||
} else {
|
||||
let split1: Vec<&str> = v.split(": ").collect();
|
||||
let header = generate_kvheader(split1[0], split1[1]);
|
||||
request.headers.push(header)
|
||||
}
|
||||
} else {
|
||||
request.body = v.to_string();
|
||||
}
|
||||
}
|
||||
return request
|
||||
}
|
||||
/// A function for converting HTTP/1.x response strings into Http1Response.
|
||||
/// Construction functions aim to be as transparent as possible so apart from turning it into a structure, the response stays relatively unchanged.
|
||||
pub fn construct_response(response: &str) -> Http1Response {
|
||||
let split = response.split("\r\n");
|
||||
let mut response = Http1Response { version: "".to_string(), status: "".to_string(), headers: vec![], body: "".to_string(), code: 0 };
|
||||
let mut reachedbody = false;
|
||||
for v in split {
|
||||
if reachedbody != true {
|
||||
if v.contains("HTTP/1.1") {
|
||||
let split1: Vec<&str> = v.split(" ").collect();
|
||||
let split2: Vec<&str> = v.split("HTTP/1.1 ").collect();
|
||||
response.version = "1.1".to_string();
|
||||
let n: i32 = FromStr::from_str(split1[1]).unwrap();
|
||||
response.status = split2[1].to_string();
|
||||
response.code = n;
|
||||
} else if v.contains("HTTP/1.0") {
|
||||
let split1: Vec<&str> = v.split(" ").collect();
|
||||
let split2: Vec<&str> = v.split("HTTP/1.0 ").collect();
|
||||
response.version = "1.0".to_string();
|
||||
let n: i32 = FromStr::from_str(split1[1]).unwrap();
|
||||
response.status = split2[1].to_string();
|
||||
response.code = n;
|
||||
} else if v == "" {
|
||||
reachedbody = true;
|
||||
} else {
|
||||
let split1: Vec<&str> = v.split(": ").collect();
|
||||
let header = generate_kvheader(split1[0], split1[1]);
|
||||
response.headers.push(header)
|
||||
}
|
||||
} else {
|
||||
response.body = v.to_string();
|
||||
}
|
||||
}
|
||||
return response
|
||||
}
|
||||
/// A function for converting Http1Request structures into HTTP/1.x request strings.
|
||||
/// Unpacking functions are simply taking the data stored in the structure and concatenating it into a string so nothing changes apart from the conversion.
|
||||
pub fn unpack_request(request: Http1Request) -> String {
|
||||
let mut unpacked = format!("{} {} HTTP/{}\r\n", request.method, request.location, request.version);
|
||||
for header in request.headers {
|
||||
unpacked = format!("{}{}: {}\r\n", unpacked, header.key, header.value);
|
||||
}
|
||||
unpacked = format!("{}\r\n{}",unpacked,request.body);
|
||||
return unpacked;
|
||||
}
|
||||
/// A function for converting Http1Response structures into HTTP/1.x response strings.
|
||||
/// Unpacking functions are simply taking the data stored in the structure and concatenating it into a string so nothing changes apart from the conversion.
|
||||
pub fn unpack_response(response: Http1Response) -> String {
|
||||
let mut unpacked = format!("HTTP/{} {}\r\n", response.version, response.status);
|
||||
for header in response.headers {
|
||||
unpacked = format!("{}{}: {}\r\n", unpacked, header.key, header.value);
|
||||
}
|
||||
unpacked = format!("{}\r\n{}",unpacked,response.body);
|
||||
return unpacked;
|
||||
}
|
||||
/// A function for downgrading request structures to HTTP/1.0, this is destructive as it removes the keep-alive and Host headers for compatibility.
|
||||
/// I don't recommend using this unless you have a specific purpose for downgrading (like accommodating strict HTTP/1.0 clients).
|
||||
pub fn downgrade_request(mut request: Http1Request) -> Http1Request {
|
||||
let mut i: usize = 0;
|
||||
let mut earmark: Vec<usize> = vec![];
|
||||
for header in &request.headers {
|
||||
if header.key == "Connection" && header.value == "keep-alive" {
|
||||
earmark.push(i);
|
||||
}
|
||||
if header.key == "Host" {
|
||||
earmark.push(i);
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
for i in earmark {
|
||||
request.headers.remove(i);
|
||||
}
|
||||
request.version = "1.0".to_string();
|
||||
return request
|
||||
}
|
||||
/// A function for upgrading request structures to HTTP/1.1, this function doesn't remove any headers.
|
||||
/// It adds on Host and keep-alive headers at user request.
|
||||
pub fn upgrade_request(mut request: Http1Request, host: &str, keepalive: bool) -> Http1Request {
|
||||
if keepalive {
|
||||
request.headers.push(generate_kvheader("Connection", "keep-alive"));
|
||||
}
|
||||
if host != "" {
|
||||
request.headers.push(generate_kvheader("Host", host));
|
||||
}
|
||||
request.version = "1.1".to_string();
|
||||
return request
|
||||
}
|
||||
/// A lookup table-like function for switching i32 codes for their human-readable string equivalent.
|
||||
fn code_to_string(code: i32) -> String {
|
||||
match code {
|
||||
100 => "100 Continue".to_string(),
|
||||
101 => "101 Switching Protocols".to_string(),
|
||||
102 => "102 Processing".to_string(),
|
||||
103 => "103 Early Hints".to_string(),
|
||||
200 => "200 OK".to_string(),
|
||||
201 => "201 Created".to_string(),
|
||||
202 => "202 Accepted".to_string(),
|
||||
203 => "203 Non-Authoritative Information".to_string(),
|
||||
204 => "204 No Content".to_string(),
|
||||
205 => "205 Reset Content".to_string(),
|
||||
206 => "206 Partial Content".to_string(),
|
||||
207 => "207 Multi-Status".to_string(),
|
||||
208 => "208 Already Reported".to_string(),
|
||||
226 => "226 IM Used".to_string(),
|
||||
300 => "300 Multiple Choices".to_string(),
|
||||
301 => "301 Moved Permanently".to_string(),
|
||||
302 => "302 Found".to_string(),
|
||||
303 => "303 See Other".to_string(),
|
||||
304 => "304 Not Modified".to_string(),
|
||||
305 => "305 Use Proxy".to_string(),
|
||||
306 => "306 Switch Proxy".to_string(),
|
||||
307 => "307 Temporary Redirect".to_string(),
|
||||
308 => "308 Permanent Redirect".to_string(),
|
||||
400 => "400 Bad Request".to_string(),
|
||||
401 => "401 Unauthorized".to_string(),
|
||||
402 => "402 Payment Required".to_string(),
|
||||
403 => "403 Forbidden".to_string(),
|
||||
404 => "404 Not Found".to_string(),
|
||||
405 => "405 Method Not Allowed".to_string(),
|
||||
406 => "406 Not Acceptable".to_string(),
|
||||
407 => "407 Proxy Authentication Required".to_string(),
|
||||
408 => "408 Request Timeout".to_string(),
|
||||
409 => "409 Conflict".to_string(),
|
||||
410 => "410 Gone".to_string(),
|
||||
411 => "411 Length Required".to_string(),
|
||||
412 => "412 Precondition Failed".to_string(),
|
||||
413 => "413 Payload Too Large".to_string(),
|
||||
414 => "414 URI Too Long".to_string(),
|
||||
415 => "415 Unsupported Media Type".to_string(),
|
||||
416 => "416 Range Not Satisfiable".to_string(),
|
||||
417 => "417 Expectation Failed".to_string(),
|
||||
418 => "418 I'm a teapot".to_string(),
|
||||
421 => "421 Misdirected Request".to_string(),
|
||||
422 => "422 Unprocessable Entity".to_string(),
|
||||
423 => "423 Locked".to_string(),
|
||||
424 => "424 Failed Dependency".to_string(),
|
||||
425 => "425 Too Early".to_string(),
|
||||
426 => "426 Upgrade Required".to_string(),
|
||||
428 => "428 Precondition Required".to_string(),
|
||||
429 => "429 Too Many Requests".to_string(),
|
||||
431 => "431 Request Header Fields Too Large".to_string(),
|
||||
451 => "451 Unavailable For Legal Reasons".to_string(),
|
||||
500 => "500 Internal Server Error".to_string(),
|
||||
501 => "501 Not Implemented".to_string(),
|
||||
502 => "502 Bad Gateway".to_string(),
|
||||
503 => "503 Service Unavailable".to_string(),
|
||||
504 => "504 Gateway Timeout".to_string(),
|
||||
505 => "505 HTTP Version Not Supported".to_string(),
|
||||
506 => "506 Variant Also Negotiates".to_string(),
|
||||
507 => "507 Insufficient Storage".to_string(),
|
||||
508 => "508 Loop Detected".to_string(),
|
||||
510 => "510 Not Extended".to_string(),
|
||||
511 => "511 Network Authentication Required".to_string(),
|
||||
_ => "500 Internal Server Error".to_string(),
|
||||
}
|
||||
}
|
||||
|
235
src/lib.rs
235
src/lib.rs
|
@ -43,238 +43,5 @@ pub fn generate_kvheader(key: &str, value: &str) -> KVHeader {
|
|||
return result
|
||||
}
|
||||
|
||||
/// The module handling HTTP/1.0 and HTTP/1.1 operations.
|
||||
/// It contains structures for HTTP/1.x requests and responses as well as functions for generating, unpacking and constructing them.
|
||||
/// It can also upgrade and downgrade HTTP/1.x requests.
|
||||
#[cfg(feature = "http1")]
|
||||
pub mod http1 {
|
||||
use super::{KVHeader, generate_kvheader};
|
||||
use std::str::FromStr;
|
||||
|
||||
/// A structure for HTTP/1.x requests.
|
||||
/// Generated with packeteer::http1::generate_request.
|
||||
#[derive(Debug)]
|
||||
pub struct Http1Request {
|
||||
pub method: String,
|
||||
pub location: String,
|
||||
pub version: String,
|
||||
pub headers: Vec<KVHeader>,
|
||||
pub body: String,
|
||||
}
|
||||
/// A structure for HTTP/1.x responses.
|
||||
/// Generated with packeteer::http1::generate_response.
|
||||
#[derive(Debug)]
|
||||
pub struct Http1Response {
|
||||
pub version: String,
|
||||
pub status: String,
|
||||
pub headers: Vec<KVHeader>,
|
||||
pub body: String,
|
||||
pub code: i32,
|
||||
}
|
||||
|
||||
/// A function for generating Http1Request structures.
|
||||
/// By default, packeteer generates HTTP/1.1 requests.
|
||||
pub fn generate_request(method: &str, host: &str, location: &str, body: &str) -> Http1Request {
|
||||
let hostkv = generate_kvheader("Host", host);
|
||||
let request = Http1Request { method: method.to_string(), location: location.to_string(), version: "1.1".to_string(), headers: vec![hostkv], body: body.to_string() };
|
||||
return request
|
||||
}
|
||||
/// A function for generating Http1Response structures.
|
||||
/// By default, packeteer generates HTTP/1.1 responses.
|
||||
pub fn generate_response(code: i32, body: &str) -> Http1Response {
|
||||
let mut xcode = code;
|
||||
if code_to_string(xcode) == "500 Internal Server Error" {
|
||||
xcode = 500;
|
||||
}
|
||||
let response = Http1Response { version: "1.1".to_string(), status: code_to_string(xcode), headers: vec![], body: body.to_string(), code: xcode };
|
||||
return response
|
||||
}
|
||||
/// A function for converting HTTP/1.x request strings into Http1Request.
|
||||
/// Construction functions aim to be as transparent as possible so apart from turning it into a structure, the request stays relatively unchanged.
|
||||
pub fn construct_request(request: &str) -> Http1Request {
|
||||
let split = request.split("\r\n");
|
||||
let mut request = Http1Request { method: "".to_string(), location: "".to_string(), version: "".to_string(), headers: vec![], body: "".to_string() };
|
||||
let mut reachedbody = false;
|
||||
for v in split {
|
||||
if reachedbody != true {
|
||||
if v.contains("HTTP/1.1") {
|
||||
let split1: Vec<&str> = v.split(" ").collect();
|
||||
request.method = split1[0].to_string();
|
||||
request.location = split1[1].to_string();
|
||||
request.version = "1.1".to_string();
|
||||
} else if v.contains("HTTP/1.0") {
|
||||
let split1: Vec<&str> = v.split(" ").collect();
|
||||
request.method = split1[0].to_string();
|
||||
request.location = split1[1].to_string();
|
||||
request.version = "1.0".to_string();
|
||||
} else if v == "" {
|
||||
reachedbody = true;
|
||||
} else {
|
||||
let split1: Vec<&str> = v.split(": ").collect();
|
||||
let header = generate_kvheader(split1[0], split1[1]);
|
||||
request.headers.push(header)
|
||||
}
|
||||
} else {
|
||||
request.body = v.to_string();
|
||||
}
|
||||
}
|
||||
return request
|
||||
}
|
||||
/// A function for converting HTTP/1.x response strings into Http1Response.
|
||||
/// Construction functions aim to be as transparent as possible so apart from turning it into a structure, the response stays relatively unchanged.
|
||||
pub fn construct_response(response: &str) -> Http1Response {
|
||||
let split = response.split("\r\n");
|
||||
let mut response = Http1Response { version: "".to_string(), status: "".to_string(), headers: vec![], body: "".to_string(), code: 0 };
|
||||
let mut reachedbody = false;
|
||||
for v in split {
|
||||
if reachedbody != true {
|
||||
if v.contains("HTTP/1.1") {
|
||||
let split1: Vec<&str> = v.split(" ").collect();
|
||||
let split2: Vec<&str> = v.split("HTTP/1.1 ").collect();
|
||||
response.version = "1.1".to_string();
|
||||
let n: i32 = FromStr::from_str(split1[1]).unwrap();
|
||||
response.status = split2[1].to_string();
|
||||
response.code = n;
|
||||
} else if v.contains("HTTP/1.0") {
|
||||
let split1: Vec<&str> = v.split(" ").collect();
|
||||
let split2: Vec<&str> = v.split("HTTP/1.0 ").collect();
|
||||
response.version = "1.0".to_string();
|
||||
let n: i32 = FromStr::from_str(split1[1]).unwrap();
|
||||
response.status = split2[1].to_string();
|
||||
response.code = n;
|
||||
} else if v == "" {
|
||||
reachedbody = true;
|
||||
} else {
|
||||
let split1: Vec<&str> = v.split(": ").collect();
|
||||
let header = generate_kvheader(split1[0], split1[1]);
|
||||
response.headers.push(header)
|
||||
}
|
||||
} else {
|
||||
response.body = v.to_string();
|
||||
}
|
||||
}
|
||||
return response
|
||||
}
|
||||
/// A function for converting Http1Request structures into HTTP/1.x request strings.
|
||||
/// Unpacking functions are simply taking the data stored in the structure and concatenating it into a string so nothing changes apart from the conversion.
|
||||
pub fn unpack_request(request: Http1Request) -> String {
|
||||
let mut unpacked = format!("{} {} HTTP/{}\r\n", request.method, request.location, request.version);
|
||||
for header in request.headers {
|
||||
unpacked = format!("{}{}: {}\r\n", unpacked, header.key, header.value);
|
||||
}
|
||||
unpacked = format!("{}\r\n{}",unpacked,request.body);
|
||||
return unpacked;
|
||||
}
|
||||
/// A function for converting Http1Response structures into HTTP/1.x response strings.
|
||||
/// Unpacking functions are simply taking the data stored in the structure and concatenating it into a string so nothing changes apart from the conversion.
|
||||
pub fn unpack_response(response: Http1Response) -> String {
|
||||
let mut unpacked = format!("HTTP/{} {}\r\n", response.version, response.status);
|
||||
for header in response.headers {
|
||||
unpacked = format!("{}{}: {}\r\n", unpacked, header.key, header.value);
|
||||
}
|
||||
unpacked = format!("{}\r\n{}",unpacked,response.body);
|
||||
return unpacked;
|
||||
}
|
||||
/// A function for downgrading request structures to HTTP/1.0, this is destructive as it removes the keep-alive and Host headers for compatibility.
|
||||
/// I don't recommend using this unless you have a specific purpose for downgrading (like accommodating strict HTTP/1.0 clients).
|
||||
pub fn downgrade_request(mut request: Http1Request) -> Http1Request {
|
||||
let mut i: usize = 0;
|
||||
let mut earmark: Vec<usize> = vec![];
|
||||
for header in &request.headers {
|
||||
if header.key == "Connection" && header.value == "keep-alive" {
|
||||
earmark.push(i);
|
||||
}
|
||||
if header.key == "Host" {
|
||||
earmark.push(i);
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
for i in earmark {
|
||||
request.headers.remove(i);
|
||||
}
|
||||
request.version = "1.0".to_string();
|
||||
return request
|
||||
}
|
||||
/// A function for upgrading request structures to HTTP/1.1, this function doesn't remove any headers.
|
||||
/// It adds on Host and keep-alive headers at user request.
|
||||
pub fn upgrade_request(mut request: Http1Request, host: &str, keepalive: bool) -> Http1Request {
|
||||
if keepalive {
|
||||
request.headers.push(generate_kvheader("Connection", "keep-alive"));
|
||||
}
|
||||
if host != "" {
|
||||
request.headers.push(generate_kvheader("Host", host));
|
||||
}
|
||||
request.version = "1.1".to_string();
|
||||
return request
|
||||
}
|
||||
|
||||
/// A lookup table-like function for switching i32 codes for their human-readable string equivalent.
|
||||
fn code_to_string(code: i32) -> String {
|
||||
match code {
|
||||
100 => "100 Continue".to_string(),
|
||||
101 => "101 Switching Protocols".to_string(),
|
||||
102 => "102 Processing".to_string(),
|
||||
103 => "103 Early Hints".to_string(),
|
||||
200 => "200 OK".to_string(),
|
||||
201 => "201 Created".to_string(),
|
||||
202 => "202 Accepted".to_string(),
|
||||
203 => "203 Non-Authoritative Information".to_string(),
|
||||
204 => "204 No Content".to_string(),
|
||||
205 => "205 Reset Content".to_string(),
|
||||
206 => "206 Partial Content".to_string(),
|
||||
207 => "207 Multi-Status".to_string(),
|
||||
208 => "208 Already Reported".to_string(),
|
||||
226 => "226 IM Used".to_string(),
|
||||
300 => "300 Multiple Choices".to_string(),
|
||||
301 => "301 Moved Permanently".to_string(),
|
||||
302 => "302 Found".to_string(),
|
||||
303 => "303 See Other".to_string(),
|
||||
304 => "304 Not Modified".to_string(),
|
||||
305 => "305 Use Proxy".to_string(),
|
||||
306 => "306 Switch Proxy".to_string(),
|
||||
307 => "307 Temporary Redirect".to_string(),
|
||||
308 => "308 Permanent Redirect".to_string(),
|
||||
400 => "400 Bad Request".to_string(),
|
||||
401 => "401 Unauthorized".to_string(),
|
||||
402 => "402 Payment Required".to_string(),
|
||||
403 => "403 Forbidden".to_string(),
|
||||
404 => "404 Not Found".to_string(),
|
||||
405 => "405 Method Not Allowed".to_string(),
|
||||
406 => "406 Not Acceptable".to_string(),
|
||||
407 => "407 Proxy Authentication Required".to_string(),
|
||||
408 => "408 Request Timeout".to_string(),
|
||||
409 => "409 Conflict".to_string(),
|
||||
410 => "410 Gone".to_string(),
|
||||
411 => "411 Length Required".to_string(),
|
||||
412 => "412 Precondition Failed".to_string(),
|
||||
413 => "413 Payload Too Large".to_string(),
|
||||
414 => "414 URI Too Long".to_string(),
|
||||
415 => "415 Unsupported Media Type".to_string(),
|
||||
416 => "416 Range Not Satisfiable".to_string(),
|
||||
417 => "417 Expectation Failed".to_string(),
|
||||
418 => "418 I'm a teapot".to_string(),
|
||||
421 => "421 Misdirected Request".to_string(),
|
||||
422 => "422 Unprocessable Entity".to_string(),
|
||||
423 => "423 Locked".to_string(),
|
||||
424 => "424 Failed Dependency".to_string(),
|
||||
425 => "425 Too Early".to_string(),
|
||||
426 => "426 Upgrade Required".to_string(),
|
||||
428 => "428 Precondition Required".to_string(),
|
||||
429 => "429 Too Many Requests".to_string(),
|
||||
431 => "431 Request Header Fields Too Large".to_string(),
|
||||
451 => "451 Unavailable For Legal Reasons".to_string(),
|
||||
500 => "500 Internal Server Error".to_string(),
|
||||
501 => "501 Not Implemented".to_string(),
|
||||
502 => "502 Bad Gateway".to_string(),
|
||||
503 => "503 Service Unavailable".to_string(),
|
||||
504 => "504 Gateway Timeout".to_string(),
|
||||
505 => "505 HTTP Version Not Supported".to_string(),
|
||||
506 => "506 Variant Also Negotiates".to_string(),
|
||||
507 => "507 Insufficient Storage".to_string(),
|
||||
508 => "508 Loop Detected".to_string(),
|
||||
510 => "510 Not Extended".to_string(),
|
||||
511 => "511 Network Authentication Required".to_string(),
|
||||
_ => "500 Internal Server Error".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
pub mod http1;
|
||||
|
|
Loading…
Reference in a new issue