///|
pub struct HarRequest {
method_value : String
url_value : String
http_version_value : String
cookies_value : Array[HarCookie]
headers_value : Array[HarNameValue]
query_value : Array[HarNameValue]
post_data_value : HarPostData?
headers_size_value : Double
body_size_value : Double
comment_value : String?
} derive(Eq, Debug)
///|
pub fn HarRequest::request_method(self : HarRequest) -> String {
self.method_value
}
///|
pub fn HarRequest::url(self : HarRequest) -> String {
self.url_value
}
///|
pub fn HarRequest::http_version(self : HarRequest) -> String {
self.http_version_value
}
///|
pub fn HarRequest::cookies(self : HarRequest) -> Array[HarCookie] {
self.cookies_value.copy()
}
///|
pub fn HarRequest::headers(self : HarRequest) -> Array[HarNameValue] {
self.headers_value.copy()
}
///|
pub fn HarRequest::query(self : HarRequest) -> Array[HarNameValue] {
self.query_value.copy()
}
///|
pub fn HarRequest::post_data(self : HarRequest) -> HarPostData? {
self.post_data_value
}
///|
pub fn HarRequest::headers_size(self : HarRequest) -> Double {
self.headers_size_value
}
///|
pub fn HarRequest::body_size(self : HarRequest) -> Double {
self.body_size_value
}
///|
pub fn HarRequest::known_headers_size(self : HarRequest) -> Double? {
known_message_size(self.headers_size_value)
}
///|
pub fn HarRequest::known_body_size(self : HarRequest) -> Double? {
known_message_size(self.body_size_value)
}
///|
pub fn HarRequest::comment(self : HarRequest) -> String? {
self.comment_value
}
///|
pub fn HarRequest::header_values(
self : HarRequest,
name : String,
) -> Array[String] {
let values : Array[String] = []
for header in self.headers_value {
if header.name_equals(name) {
values.push(header.value())
}
}
values
}
///|
pub fn HarRequest::query_values(
self : HarRequest,
name : String,
) -> Array[String] {
let values : Array[String] = []
for parameter in self.query_value {
if parameter.name() == name {
values.push(parameter.value())
}
}
values
}
///|
pub fn HarRequest::cookie_values(
self : HarRequest,
name : String,
) -> Array[String] {
let values : Array[String] = []
for cookie in self.cookies_value {
if cookie.name() == name {
values.push(cookie.value())
}
}
values
}
///|
pub fn HarRequest::has_body(self : HarRequest) -> Bool {
self.post_data_value is Some(_) || self.body_size_value > 0.0
}
///|
pub fn HarRequest::is_secure(self : HarRequest) -> Bool {
self.url_value.to_lower().has_prefix("https://")
}
///|
pub fn HarRequest::method_is(self : HarRequest, expected : String) -> Bool {
self.method_value.to_upper() == expected.to_upper()
}
///|
pub struct HarResponse {
status_value : Double
status_text_value : String
http_version_value : String
cookies_value : Array[HarCookie]
headers_value : Array[HarNameValue]
content_value : HarContent
redirect_url_value : String
headers_size_value : Double
body_size_value : Double
comment_value : String?
} derive(Eq, Debug)
///|
pub fn HarResponse::status(self : HarResponse) -> Double {
self.status_value
}
///|
pub fn HarResponse::status_text(self : HarResponse) -> String {
self.status_text_value
}
///|
pub fn HarResponse::http_version(self : HarResponse) -> String {
self.http_version_value
}
///|
pub fn HarResponse::cookies(self : HarResponse) -> Array[HarCookie] {
self.cookies_value.copy()
}
///|
pub fn HarResponse::headers(self : HarResponse) -> Array[HarNameValue] {
self.headers_value.copy()
}
///|
pub fn HarResponse::content(self : HarResponse) -> HarContent {
self.content_value
}
///|
pub fn HarResponse::redirect_url(self : HarResponse) -> String {
self.redirect_url_value
}
///|
pub fn HarResponse::headers_size(self : HarResponse) -> Double {
self.headers_size_value
}
///|
pub fn HarResponse::body_size(self : HarResponse) -> Double {
self.body_size_value
}
///|
pub fn HarResponse::known_headers_size(self : HarResponse) -> Double? {
known_message_size(self.headers_size_value)
}
///|
pub fn HarResponse::known_body_size(self : HarResponse) -> Double? {
known_message_size(self.body_size_value)
}
///|
pub fn HarResponse::comment(self : HarResponse) -> String? {
self.comment_value
}
///|
pub fn HarResponse::header_values(
self : HarResponse,
name : String,
) -> Array[String] {
let values : Array[String] = []
for header in self.headers_value {
if header.name_equals(name) {
values.push(header.value())
}
}
values
}
///|
pub fn HarResponse::status_class(self : HarResponse) -> String {
if self.status_value >= 100.0 && self.status_value < 200.0 {
"informational"
} else if self.status_value < 300.0 {
"success"
} else if self.status_value < 400.0 {
"redirect"
} else if self.status_value < 500.0 {
"client_error"
} else if self.status_value < 600.0 {
"server_error"
} else {
"other"
}
}
///|
pub fn HarResponse::is_success(self : HarResponse) -> Bool {
self.status_value >= 200.0 && self.status_value < 300.0
}
///|
pub fn HarResponse::is_redirect(self : HarResponse) -> Bool {
self.status_value >= 300.0 && self.status_value < 400.0
}
///|
pub fn HarResponse::is_error(self : HarResponse) -> Bool {
self.status_value >= 400.0
}
///|
fn known_message_size(value : Double) -> Double? {
if value < 0.0 {
None
} else {
Some(value)
}
}
///|
fn validate_message_size(
value : Double,
path : String,
) -> Result[Unit, HarError] {
if value.trunc() != value {
Err(HarError::new(InvalidSize, path, "message size must be an integer"))
} else if value < -1.0 {
Err(
HarError::new(
InvalidSize,
path,
"message size must be -1 or non-negative",
),
)
} else {
Ok(())
}
}
///|
fn validate_request_method(
verb : String,
path : String,
) -> Result[Unit, HarError] {
if verb.trim().is_empty() {
return Err(HarError::new(InvalidMethod, path, "method cannot be empty"))
}
for character in verb {
let code = character.to_int()
if code <= 32 || code >= 127 {
return Err(
HarError::new(
InvalidMethod,
path,
"method must contain visible ASCII token characters",
),
)
}
}
Ok(())
}
///|
fn validate_request_url(url : String, path : String) -> Result[Unit, HarError] {
if url.trim().is_empty() {
Err(HarError::new(InvalidUrl, path, "request URL cannot be empty"))
} else {
Ok(())
}
}
///|
fn parse_request_cursor(cursor : JsonCursor) -> Result[HarRequest, HarError] {
let verb = match cursor.required_string("method") {
Ok(value) => value
Err(error) => return Err(error)
}
match
validate_request_method(verb, append_json_field(cursor.path(), "method")) {
Ok(_) => ()
Err(error) => return Err(error)
}
let url = match cursor.required_string("url") {
Ok(value) => value
Err(error) => return Err(error)
}
match validate_request_url(url, append_json_field(cursor.path(), "url")) {
Ok(_) => ()
Err(error) => return Err(error)
}
let http_version = match cursor.required_string("httpVersion") {
Ok(value) => value
Err(error) => return Err(error)
}
let cookie_cursors = match cursor.required_array("cookies") {
Ok(value) => value
Err(error) => return Err(error)
}
let cookies = match parse_cookie_array(cookie_cursors) {
Ok(value) => value
Err(error) => return Err(error)
}
let header_cursors = match cursor.required_array("headers") {
Ok(value) => value
Err(error) => return Err(error)
}
let headers = match parse_name_value_array(header_cursors) {
Ok(value) => value
Err(error) => return Err(error)
}
let query_cursors = match cursor.required_array("queryString") {
Ok(value) => value
Err(error) => return Err(error)
}
let query = match parse_name_value_array(query_cursors) {
Ok(value) => value
Err(error) => return Err(error)
}
let post_cursor = match cursor.optional_object("postData") {
Ok(value) => value
Err(error) => return Err(error)
}
let post_data = match post_cursor {
Some(value) =>
match parse_post_data_cursor(value) {
Ok(post) => Some(post)
Err(error) => return Err(error)
}
None => None
}
let headers_size = match cursor.required_number("headersSize") {
Ok(value) => value
Err(error) => return Err(error)
}
match
validate_message_size(
headers_size,
append_json_field(cursor.path(), "headersSize"),
) {
Ok(_) => ()
Err(error) => return Err(error)
}
let body_size = match cursor.required_number("bodySize") {
Ok(value) => value
Err(error) => return Err(error)
}
match
validate_message_size(
body_size,
append_json_field(cursor.path(), "bodySize"),
) {
Ok(_) => ()
Err(error) => return Err(error)
}
let comment = match cursor.optional_string("comment") {
Ok(value) => value
Err(error) => return Err(error)
}
Ok({
method_value: verb,
url_value: url,
http_version_value: http_version,
cookies_value: cookies,
headers_value: headers,
query_value: query,
post_data_value: post_data,
headers_size_value: headers_size,
body_size_value: body_size,
comment_value: comment,
})
}
///|
fn parse_response_cursor(cursor : JsonCursor) -> Result[HarResponse, HarError] {
let status = match cursor.required_number("status") {
Ok(value) => value
Err(error) => return Err(error)
}
if status.trunc() != status {
return Err(
HarError::new(
InvalidStatus,
append_json_field(cursor.path(), "status"),
"status must be an integer",
),
)
}
if status < 0.0 || status > 999.0 {
return Err(
HarError::new(
InvalidStatus,
append_json_field(cursor.path(), "status"),
"status must be between 0 and 999",
),
)
}
let status_text = match cursor.required_string("statusText") {
Ok(value) => value
Err(error) => return Err(error)
}
let http_version = match cursor.required_string("httpVersion") {
Ok(value) => value
Err(error) => return Err(error)
}
let cookie_cursors = match cursor.required_array("cookies") {
Ok(value) => value
Err(error) => return Err(error)
}
let cookies = match parse_cookie_array(cookie_cursors) {
Ok(value) => value
Err(error) => return Err(error)
}
let header_cursors = match cursor.required_array("headers") {
Ok(value) => value
Err(error) => return Err(error)
}
let headers = match parse_name_value_array(header_cursors) {
Ok(value) => value
Err(error) => return Err(error)
}
let content_cursor = match cursor.required_object("content") {
Ok(value) => value
Err(error) => return Err(error)
}
let content = match parse_content_cursor(content_cursor) {
Ok(value) => value
Err(error) => return Err(error)
}
let redirect_url = match cursor.required_string("redirectURL") {
Ok(value) => value
Err(error) => return Err(error)
}
let headers_size = match cursor.required_number("headersSize") {
Ok(value) => value
Err(error) => return Err(error)
}
match
validate_message_size(
headers_size,
append_json_field(cursor.path(), "headersSize"),
) {
Ok(_) => ()
Err(error) => return Err(error)
}
let body_size = match cursor.required_number("bodySize") {
Ok(value) => value
Err(error) => return Err(error)
}
match
validate_message_size(
body_size,
append_json_field(cursor.path(), "bodySize"),
) {
Ok(_) => ()
Err(error) => return Err(error)
}
let comment = match cursor.optional_string("comment") {
Ok(value) => value
Err(error) => return Err(error)
}
Ok({
status_value: status,
status_text_value: status_text,
http_version_value: http_version,
cookies_value: cookies,
headers_value: headers,
content_value: content,
redirect_url_value: redirect_url,
headers_size_value: headers_size,
body_size_value: body_size,
comment_value: comment,
})
}
///|
pub fn parse_request(input : String) -> Result[HarRequest, HarError] {
let cursor = match parse_json_cursor(input) {
Ok(value) => value
Err(error) => return Err(error)
}
parse_request_cursor(cursor)
}
///|
pub fn parse_response(input : String) -> Result[HarResponse, HarError] {
let cursor = match parse_json_cursor(input) {
Ok(value) => value
Err(error) => return Err(error)
}
parse_response_cursor(cursor)
}