e7738de6d2
CI / Deep Native Runtime Cases (1/6) (push) Has been skipped
CI / Native Preflight (push) Failing after 1s
CI / Native Runtime Cases (1/2) (push) Failing after 0s
CI / Native Runtime Cases (2/2) (push) Failing after 1s
CI / Native Metadata Reports (push) Failing after 0s
CI / Native Direct Backend Artifacts (push) Failing after 0s
CI / Native Sanitizer Smoke (push) Failing after 1s
CI / Command Contract Snapshots (push) Failing after 1s
CI / Deep Conformance Suite (push) Has been skipped
CI / Graph Build Perf (push) Failing after 1s
CI / Deep Native Preflight (push) Has been skipped
CI / Deep Native Runtime Cases (2/6) (push) Has been skipped
CI / Deep Native Runtime Cases (3/6) (push) Has been skipped
CI / Conformance Suite (push) Failing after 1s
CI / Workspace Checks (push) Failing after 0s
CI / Deep Native Runtime Cases (5/6) (push) Has been skipped
CI / Deep Native Runtime Cases (6/6) (push) Has been skipped
CI / Deep Native Runtime Cases (4/6) (push) Has been skipped
CI / Deep Graph Build Perf (push) Has been skipped
4091 lines
137 KiB
Plaintext
4091 lines
137 KiB
Plaintext
fn __zero_std_http_token_char(byte: u8) -> Bool {
|
|
return byte >= 65_u8 && byte <= 90_u8 || byte >= 97_u8 && byte <= 122_u8 || byte >= 48_u8 && byte <= 57_u8 || byte == 33_u8 || byte == 35_u8 || byte == 36_u8 || byte == 37_u8 || byte == 38_u8 || byte == 39_u8 || byte == 42_u8 || byte == 43_u8 || byte == 45_u8 || byte == 46_u8 || byte == 94_u8 || byte == 95_u8 || byte == 96_u8 || byte == 124_u8 || byte == 126_u8
|
|
}
|
|
|
|
fn __zero_std_http_method_valid(method: Span<u8>) -> Bool {
|
|
if std.mem.len(method) == 0 {
|
|
return false
|
|
}
|
|
var index: usize = 0
|
|
while index < std.mem.len(method) {
|
|
if !__zero_std_http_token_char(method[index]) {
|
|
return false
|
|
}
|
|
index = index + 1
|
|
}
|
|
return true
|
|
}
|
|
|
|
fn __zero_std_http_target_valid(target: Span<u8>) -> Bool {
|
|
if std.mem.len(target) == 0 {
|
|
return false
|
|
}
|
|
var index: usize = 0
|
|
while index < std.mem.len(target) {
|
|
if target[index] <= 32_u8 {
|
|
return false
|
|
}
|
|
index = index + 1
|
|
}
|
|
return true
|
|
}
|
|
|
|
fn __zero_std_http_start_line_valid(line: Span<u8>) -> Bool {
|
|
var space: usize = 0
|
|
while space < std.mem.len(line) && line[space] != 32_u8 {
|
|
space = space + 1
|
|
}
|
|
if space == 0 || space + 1 >= std.mem.len(line) {
|
|
return false
|
|
}
|
|
let method: Span<u8> = line[..space]
|
|
let target: Span<u8> = line[space + 1..]
|
|
return __zero_std_http_method_valid(method) && __zero_std_http_target_valid(target)
|
|
}
|
|
|
|
fn __zero_std_http_first_line_end(bytes: Span<u8>) -> Maybe<usize> {
|
|
var end: usize = 0
|
|
while end < std.mem.len(bytes) && bytes[end] != 10_u8 {
|
|
end = end + 1
|
|
}
|
|
if end >= std.mem.len(bytes) {
|
|
return null
|
|
}
|
|
if end > 0 && bytes[end - 1] == 13_u8 {
|
|
return end - 1
|
|
}
|
|
return end
|
|
}
|
|
|
|
fn __zero_std_http_body_start(bytes: Span<u8>) -> Maybe<usize> {
|
|
var start: usize = 0
|
|
while start < std.mem.len(bytes) {
|
|
var end: usize = start
|
|
while end < std.mem.len(bytes) && bytes[end] != 10_u8 {
|
|
end = end + 1
|
|
}
|
|
var line_end: usize = end
|
|
if line_end > start && bytes[line_end - 1] == 13_u8 {
|
|
line_end = line_end - 1
|
|
}
|
|
var next: usize = end
|
|
if end < std.mem.len(bytes) {
|
|
next = end + 1
|
|
}
|
|
if line_end == start {
|
|
return next
|
|
}
|
|
start = next
|
|
}
|
|
return null
|
|
}
|
|
|
|
fn __zero_std_http_write(buffer: MutSpan<u8>, offset: usize, bytes: Span<u8>) -> Maybe<usize> {
|
|
return std.io.writeSpan(buffer, offset, bytes)
|
|
}
|
|
|
|
fn __zero_std_http_write_usize(buffer: MutSpan<u8>, offset: usize, value: usize) -> Maybe<usize> {
|
|
if offset > std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
let written: Maybe<Span<u8>> = std.fmt.usize(buffer[offset..], value)
|
|
if !written.has {
|
|
return null
|
|
}
|
|
return offset + std.mem.len(written.value)
|
|
}
|
|
|
|
fn __zero_std_http_write_content_length(buffer: MutSpan<u8>, offset: usize, len: usize) -> Maybe<usize> {
|
|
let prefix: Maybe<usize> = __zero_std_http_write(buffer, offset, "content-length: ")
|
|
if !prefix.has {
|
|
return null
|
|
}
|
|
let count: Maybe<usize> = __zero_std_http_write_usize(buffer, prefix.value, len)
|
|
if !count.has {
|
|
return null
|
|
}
|
|
return __zero_std_http_write(buffer, count.value, "\r\n")
|
|
}
|
|
|
|
fn __zero_std_http_status_reason(status: u16) -> String {
|
|
if status == 100_u16 {
|
|
return "Continue"
|
|
}
|
|
if status == 200_u16 {
|
|
return "OK"
|
|
}
|
|
if status == 201_u16 {
|
|
return "Created"
|
|
}
|
|
if status == 202_u16 {
|
|
return "Accepted"
|
|
}
|
|
if status == 204_u16 {
|
|
return "No Content"
|
|
}
|
|
if status == 301_u16 {
|
|
return "Moved Permanently"
|
|
}
|
|
if status == 302_u16 {
|
|
return "Found"
|
|
}
|
|
if status == 303_u16 {
|
|
return "See Other"
|
|
}
|
|
if status == 304_u16 {
|
|
return "Not Modified"
|
|
}
|
|
if status == 307_u16 {
|
|
return "Temporary Redirect"
|
|
}
|
|
if status == 308_u16 {
|
|
return "Permanent Redirect"
|
|
}
|
|
if status == 400_u16 {
|
|
return "Bad Request"
|
|
}
|
|
if status == 401_u16 {
|
|
return "Unauthorized"
|
|
}
|
|
if status == 403_u16 {
|
|
return "Forbidden"
|
|
}
|
|
if status == 404_u16 {
|
|
return "Not Found"
|
|
}
|
|
if status == 405_u16 {
|
|
return "Method Not Allowed"
|
|
}
|
|
if status == 409_u16 {
|
|
return "Conflict"
|
|
}
|
|
if status == 422_u16 {
|
|
return "Unprocessable Content"
|
|
}
|
|
if status == 429_u16 {
|
|
return "Too Many Requests"
|
|
}
|
|
if status == 500_u16 {
|
|
return "Internal Server Error"
|
|
}
|
|
if status == 502_u16 {
|
|
return "Bad Gateway"
|
|
}
|
|
if status == 503_u16 {
|
|
return "Service Unavailable"
|
|
}
|
|
return "Unknown"
|
|
}
|
|
|
|
fn __zero_std_http_status_is_informational(status: u16) -> Bool {
|
|
return status >= 100_u16 && status < 200_u16
|
|
}
|
|
|
|
fn __zero_std_http_status_is_success(status: u16) -> Bool {
|
|
return status >= 200_u16 && status < 300_u16
|
|
}
|
|
|
|
fn __zero_std_http_status_is_redirect(status: u16) -> Bool {
|
|
return status >= 300_u16 && status < 400_u16
|
|
}
|
|
|
|
fn __zero_std_http_status_is_client_error(status: u16) -> Bool {
|
|
return status >= 400_u16 && status < 500_u16
|
|
}
|
|
|
|
fn __zero_std_http_status_is_server_error(status: u16) -> Bool {
|
|
return status >= 500_u16 && status < 600_u16
|
|
}
|
|
|
|
fn __zero_std_http_write_request(buffer: MutSpan<u8>, start_line: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
if !__zero_std_http_start_line_valid(start_line) {
|
|
return null
|
|
}
|
|
var offset: usize = 0
|
|
let wrote_line_text: Maybe<usize> = __zero_std_http_write(buffer, offset, start_line)
|
|
if !wrote_line_text.has {
|
|
return null
|
|
}
|
|
offset = wrote_line_text.value
|
|
let wrote_line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !wrote_line.has {
|
|
return null
|
|
}
|
|
offset = wrote_line.value
|
|
if std.mem.len(body) > 0 {
|
|
let wrote_length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, std.mem.len(body))
|
|
if !wrote_length.has {
|
|
return null
|
|
}
|
|
offset = wrote_length.value
|
|
}
|
|
let wrote_blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !wrote_blank.has {
|
|
return null
|
|
}
|
|
offset = wrote_blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_json_request(buffer: MutSpan<u8>, start_line: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
if !__zero_std_http_start_line_valid(start_line) {
|
|
return null
|
|
}
|
|
var offset: usize = 0
|
|
let wrote_line_text: Maybe<usize> = __zero_std_http_write(buffer, offset, start_line)
|
|
if !wrote_line_text.has {
|
|
return null
|
|
}
|
|
offset = wrote_line_text.value
|
|
let wrote_line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\ncontent-type: application/json\r\n")
|
|
if !wrote_line.has {
|
|
return null
|
|
}
|
|
offset = wrote_line.value
|
|
let wrote_length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, std.mem.len(body))
|
|
if !wrote_length.has {
|
|
return null
|
|
}
|
|
offset = wrote_length.value
|
|
let wrote_blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !wrote_blank.has {
|
|
return null
|
|
}
|
|
offset = wrote_blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_method_target_start_line(buffer: MutSpan<u8>, method: Span<u8>, target: Span<u8>) -> Maybe<Span<u8>> {
|
|
if !__zero_std_http_method_valid(method) || !__zero_std_http_target_valid(target) {
|
|
return null
|
|
}
|
|
var offset: usize = 0
|
|
let wrote_method: Maybe<usize> = __zero_std_http_write(buffer, offset, method)
|
|
if !wrote_method.has {
|
|
return null
|
|
}
|
|
offset = wrote_method.value
|
|
let wrote_space: Maybe<usize> = __zero_std_http_write(buffer, offset, " ")
|
|
if !wrote_space.has {
|
|
return null
|
|
}
|
|
offset = wrote_space.value
|
|
let wrote_target: Maybe<usize> = __zero_std_http_write(buffer, offset, target)
|
|
if !wrote_target.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_target.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_method_request(buffer: MutSpan<u8>, method: Span<u8>, target: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
if !__zero_std_http_method_valid(method) || !__zero_std_http_target_valid(target) {
|
|
return null
|
|
}
|
|
var offset: usize = 0
|
|
let wrote_method: Maybe<usize> = __zero_std_http_write(buffer, offset, method)
|
|
if !wrote_method.has {
|
|
return null
|
|
}
|
|
offset = wrote_method.value
|
|
let wrote_space: Maybe<usize> = __zero_std_http_write(buffer, offset, " ")
|
|
if !wrote_space.has {
|
|
return null
|
|
}
|
|
offset = wrote_space.value
|
|
let wrote_target: Maybe<usize> = __zero_std_http_write(buffer, offset, target)
|
|
if !wrote_target.has {
|
|
return null
|
|
}
|
|
offset = wrote_target.value
|
|
let wrote_line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !wrote_line.has {
|
|
return null
|
|
}
|
|
offset = wrote_line.value
|
|
if std.mem.len(body) > 0 {
|
|
let wrote_length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, std.mem.len(body))
|
|
if !wrote_length.has {
|
|
return null
|
|
}
|
|
offset = wrote_length.value
|
|
}
|
|
let wrote_blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !wrote_blank.has {
|
|
return null
|
|
}
|
|
offset = wrote_blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_json_method_request(buffer: MutSpan<u8>, method: Span<u8>, target: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
if !__zero_std_http_method_valid(method) || !__zero_std_http_target_valid(target) {
|
|
return null
|
|
}
|
|
var offset: usize = 0
|
|
let wrote_method: Maybe<usize> = __zero_std_http_write(buffer, offset, method)
|
|
if !wrote_method.has {
|
|
return null
|
|
}
|
|
offset = wrote_method.value
|
|
let wrote_space: Maybe<usize> = __zero_std_http_write(buffer, offset, " ")
|
|
if !wrote_space.has {
|
|
return null
|
|
}
|
|
offset = wrote_space.value
|
|
let wrote_target: Maybe<usize> = __zero_std_http_write(buffer, offset, target)
|
|
if !wrote_target.has {
|
|
return null
|
|
}
|
|
offset = wrote_target.value
|
|
let wrote_line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !wrote_line.has {
|
|
return null
|
|
}
|
|
offset = wrote_line.value
|
|
let wrote_type: Maybe<usize> = __zero_std_http_write(buffer, offset, "content-type: application/json\r\n")
|
|
if !wrote_type.has {
|
|
return null
|
|
}
|
|
offset = wrote_type.value
|
|
let wrote_length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, std.mem.len(body))
|
|
if !wrote_length.has {
|
|
return null
|
|
}
|
|
offset = wrote_length.value
|
|
let wrote_blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !wrote_blank.has {
|
|
return null
|
|
}
|
|
offset = wrote_blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_get_request(buffer: MutSpan<u8>, target: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_http_write_method_request(buffer, "GET", target, "")
|
|
}
|
|
|
|
fn __zero_std_http_write_head_request(buffer: MutSpan<u8>, target: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_http_write_method_request(buffer, "HEAD", target, "")
|
|
}
|
|
|
|
fn __zero_std_http_write_delete_request(buffer: MutSpan<u8>, target: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_http_write_method_request(buffer, "DELETE", target, "")
|
|
}
|
|
|
|
fn __zero_std_http_write_post_json_request(buffer: MutSpan<u8>, target: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_http_write_json_method_request(buffer, "POST", target, body)
|
|
}
|
|
|
|
fn __zero_std_http_write_put_json_request(buffer: MutSpan<u8>, target: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_http_write_json_method_request(buffer, "PUT", target, body)
|
|
}
|
|
|
|
fn __zero_std_http_write_patch_json_request(buffer: MutSpan<u8>, target: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_http_write_json_method_request(buffer, "PATCH", target, body)
|
|
}
|
|
|
|
fn __zero_std_http_write_response(buffer: MutSpan<u8>, status: u16, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
var offset: usize = 0
|
|
let prefix: Maybe<usize> = __zero_std_http_write(buffer, offset, "HTTP/1.1 ")
|
|
if !prefix.has {
|
|
return null
|
|
}
|
|
offset = prefix.value
|
|
let code: Maybe<usize> = __zero_std_http_write_usize(buffer, offset, status as usize)
|
|
if !code.has {
|
|
return null
|
|
}
|
|
offset = code.value
|
|
let space: Maybe<usize> = __zero_std_http_write(buffer, offset, " ")
|
|
if !space.has {
|
|
return null
|
|
}
|
|
offset = space.value
|
|
let reason: Maybe<usize> = __zero_std_http_write(buffer, offset, std.mem.span(__zero_std_http_status_reason(status)))
|
|
if !reason.has {
|
|
return null
|
|
}
|
|
offset = reason.value
|
|
let line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\nconnection: close\r\n")
|
|
if !line.has {
|
|
return null
|
|
}
|
|
offset = line.value
|
|
let length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, std.mem.len(body))
|
|
if !length.has {
|
|
return null
|
|
}
|
|
offset = length.value
|
|
let blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !blank.has {
|
|
return null
|
|
}
|
|
offset = blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_json_response(buffer: MutSpan<u8>, status: u16, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
var offset: usize = 0
|
|
let prefix: Maybe<usize> = __zero_std_http_write(buffer, offset, "HTTP/1.1 ")
|
|
if !prefix.has {
|
|
return null
|
|
}
|
|
offset = prefix.value
|
|
let code: Maybe<usize> = __zero_std_http_write_usize(buffer, offset, status as usize)
|
|
if !code.has {
|
|
return null
|
|
}
|
|
offset = code.value
|
|
let space: Maybe<usize> = __zero_std_http_write(buffer, offset, " ")
|
|
if !space.has {
|
|
return null
|
|
}
|
|
offset = space.value
|
|
let reason: Maybe<usize> = __zero_std_http_write(buffer, offset, std.mem.span(__zero_std_http_status_reason(status)))
|
|
if !reason.has {
|
|
return null
|
|
}
|
|
offset = reason.value
|
|
let line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\ncontent-type: application/json\r\nconnection: close\r\n")
|
|
if !line.has {
|
|
return null
|
|
}
|
|
offset = line.value
|
|
let length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, std.mem.len(body))
|
|
if !length.has {
|
|
return null
|
|
}
|
|
offset = length.value
|
|
let blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !blank.has {
|
|
return null
|
|
}
|
|
offset = blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_request_method_name(request: Span<u8>) -> Maybe<Span<u8>> {
|
|
let line_end: Maybe<usize> = __zero_std_http_first_line_end(request)
|
|
if !line_end.has {
|
|
return null
|
|
}
|
|
var space: usize = 0
|
|
while space < line_end.value && request[space] != 32_u8 {
|
|
space = space + 1
|
|
}
|
|
if space == 0 || space >= line_end.value {
|
|
return null
|
|
}
|
|
let method: Span<u8> = request[..space]
|
|
if !__zero_std_http_method_valid(method) {
|
|
return null
|
|
}
|
|
return method
|
|
}
|
|
|
|
fn __zero_std_http_request_target(request: Span<u8>) -> Maybe<Span<u8>> {
|
|
let line_end: Maybe<usize> = __zero_std_http_first_line_end(request)
|
|
if !line_end.has {
|
|
return null
|
|
}
|
|
var space: usize = 0
|
|
while space < line_end.value && request[space] != 32_u8 {
|
|
space = space + 1
|
|
}
|
|
if space == 0 || space + 1 >= line_end.value {
|
|
return null
|
|
}
|
|
var index: usize = space + 1
|
|
while index < line_end.value && request[index] != 32_u8 {
|
|
if request[index] <= 32_u8 {
|
|
return null
|
|
}
|
|
index = index + 1
|
|
}
|
|
if index == space + 1 {
|
|
return null
|
|
}
|
|
if index < line_end.value {
|
|
var version_start: usize = index
|
|
while version_start < line_end.value && request[version_start] == 32_u8 {
|
|
version_start = version_start + 1
|
|
}
|
|
if version_start < line_end.value {
|
|
let version: Span<u8> = request[version_start..line_end.value]
|
|
if !std.mem.eql(version, "HTTP/1.0") && !std.mem.eql(version, "HTTP/1.1") {
|
|
return null
|
|
}
|
|
}
|
|
}
|
|
return request[space + 1..index]
|
|
}
|
|
|
|
fn __zero_std_http_request_path(request: Span<u8>) -> Maybe<Span<u8>> {
|
|
let target: Maybe<Span<u8>> = __zero_std_http_request_target(request)
|
|
if !target.has {
|
|
return null
|
|
}
|
|
let absolute_path: Span<u8> = std.url.path(target.value)
|
|
if std.mem.len(absolute_path) > 0 {
|
|
return absolute_path
|
|
}
|
|
if std.str.startsWith(target.value, "http://") || std.str.startsWith(target.value, "https://") {
|
|
let root: Span<u8> = "/"
|
|
return root
|
|
}
|
|
var end: usize = 0
|
|
while end < std.mem.len(target.value) && target.value[end] != 63_u8 && target.value[end] != 35_u8 {
|
|
end = end + 1
|
|
}
|
|
if end == 0 {
|
|
return null
|
|
}
|
|
return target.value[..end]
|
|
}
|
|
|
|
fn __zero_std_http_request_query(request: Span<u8>) -> Maybe<Span<u8>> {
|
|
let target: Maybe<Span<u8>> = __zero_std_http_request_target(request)
|
|
if !target.has {
|
|
return null
|
|
}
|
|
let absolute_query: Maybe<Span<u8>> = std.url.query(target.value)
|
|
if absolute_query.has {
|
|
return absolute_query.value
|
|
}
|
|
var start: usize = 0
|
|
while start < std.mem.len(target.value) && target.value[start] != 63_u8 {
|
|
if target.value[start] == 35_u8 {
|
|
return null
|
|
}
|
|
start = start + 1
|
|
}
|
|
if start >= std.mem.len(target.value) {
|
|
return null
|
|
}
|
|
start = start + 1
|
|
var end: usize = start
|
|
while end < std.mem.len(target.value) && target.value[end] != 35_u8 {
|
|
end = end + 1
|
|
}
|
|
return target.value[start..end]
|
|
}
|
|
|
|
fn __zero_std_http_request_query_value(request: Span<u8>, name: Span<u8>) -> Maybe<Span<u8>> {
|
|
let query: Maybe<Span<u8>> = __zero_std_http_request_query(request)
|
|
if !query.has {
|
|
return null
|
|
}
|
|
return std.url.queryValue(query.value, name)
|
|
}
|
|
|
|
fn __zero_std_http_request_header(request: Span<u8>, name: Span<u8>) -> Maybe<Span<u8>> {
|
|
if std.mem.len(name) == 0 {
|
|
return null
|
|
}
|
|
let body_start: Maybe<usize> = __zero_std_http_body_start(request)
|
|
if !body_start.has {
|
|
return null
|
|
}
|
|
var start: usize = std.io.nextLineStart(request, 0)
|
|
while start < body_start.value {
|
|
let line: Maybe<Span<u8>> = std.io.nextLine(request, start)
|
|
if !line.has || std.mem.len(line.value) == 0 {
|
|
return null
|
|
}
|
|
var colon: usize = 0
|
|
while colon < std.mem.len(line.value) && line.value[colon] != 58_u8 {
|
|
colon = colon + 1
|
|
}
|
|
if colon > 0 && colon < std.mem.len(line.value) {
|
|
let header_name: Span<u8> = line.value[..colon]
|
|
if std.str.eqlIgnoreAsciiCase(header_name, name) {
|
|
return std.str.trimAscii(line.value[colon + 1..])
|
|
}
|
|
}
|
|
start = std.io.nextLineStart(request, start)
|
|
}
|
|
return null
|
|
}
|
|
|
|
fn __zero_std_http_request_body(request: Span<u8>) -> Maybe<Span<u8>> {
|
|
let start: Maybe<usize> = __zero_std_http_body_start(request)
|
|
if !start.has {
|
|
return null
|
|
}
|
|
return request[start.value..]
|
|
}
|
|
|
|
fn __zero_std_http_request_body_within(request: Span<u8>, max: usize) -> Maybe<Span<u8>> {
|
|
let body: Maybe<Span<u8>> = __zero_std_http_request_body(request)
|
|
if !body.has || std.mem.len(body.value) > max {
|
|
return null
|
|
}
|
|
return body.value
|
|
}
|
|
|
|
fn __zero_std_http_request_matches(request: Span<u8>, method: Span<u8>, path: Span<u8>) -> Bool {
|
|
let found_method: Maybe<Span<u8>> = __zero_std_http_request_method_name(request)
|
|
if !found_method.has {
|
|
return false
|
|
}
|
|
if !std.mem.eql(found_method.value, method) {
|
|
return false
|
|
}
|
|
let found_path: Maybe<Span<u8>> = __zero_std_http_request_path(request)
|
|
if !found_path.has {
|
|
return false
|
|
}
|
|
return std.mem.eql(found_path.value, path)
|
|
}
|
|
|
|
fn __zero_std_http_header_bytes(response: Span<u8>, value: HttpHeaderValue) -> Maybe<Span<u8>> {
|
|
if !std.http.headerFound(value) {
|
|
return null
|
|
}
|
|
let offset: usize = std.http.headerOffset(value)
|
|
let len: usize = std.http.headerLen(value)
|
|
if offset > std.mem.len(response) || len > std.mem.len(response) - offset {
|
|
return null
|
|
}
|
|
return response[offset..offset + len]
|
|
}
|
|
|
|
fn __zero_std_http_response_body(response: Span<u8>, result: HttpResult) -> Maybe<Span<u8>> {
|
|
if std.http.resultError(result) != std.http.errorNone() {
|
|
return null
|
|
}
|
|
let offset: usize = std.http.responseBodyOffset(response)
|
|
let len: usize = std.http.resultBodyLen(result)
|
|
if offset > std.mem.len(response) || len > std.mem.len(response) - offset {
|
|
return null
|
|
}
|
|
return response[offset..offset + len]
|
|
}
|
|
|
|
fn __zero_std_http_error_name(code: u32) -> String {
|
|
if code == 0_u32 {
|
|
return "ok"
|
|
}
|
|
if code == 1_u32 {
|
|
return "invalid_url"
|
|
}
|
|
if code == 2_u32 {
|
|
return "unsupported_protocol"
|
|
}
|
|
if code == 3_u32 {
|
|
return "dns"
|
|
}
|
|
if code == 4_u32 {
|
|
return "connect"
|
|
}
|
|
if code == 5_u32 {
|
|
return "tls"
|
|
}
|
|
if code == 6_u32 {
|
|
return "timeout"
|
|
}
|
|
if code == 7_u32 {
|
|
return "too_large"
|
|
}
|
|
if code == 8_u32 {
|
|
return "provider_unavailable"
|
|
}
|
|
if code == 9_u32 {
|
|
return "io"
|
|
}
|
|
if code == 10_u32 {
|
|
return "invalid_request"
|
|
}
|
|
return "unknown"
|
|
}
|
|
|
|
fn __zero_std_http_write_json_ok(buffer: MutSpan<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return std.http.writeJsonResponse(buffer, 200_u16, body)
|
|
}
|
|
|
|
fn __zero_std_http_write_json_created(buffer: MutSpan<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return std.http.writeJsonResponse(buffer, 201_u16, body)
|
|
}
|
|
|
|
fn __zero_std_http_write_json_bad_request(buffer: MutSpan<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return std.http.writeJsonResponse(buffer, 400_u16, body)
|
|
}
|
|
|
|
fn __zero_std_http_write_json_not_found(buffer: MutSpan<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return std.http.writeJsonResponse(buffer, 404_u16, body)
|
|
}
|
|
|
|
fn __zero_std_http_write_json_method_not_allowed(buffer: MutSpan<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return std.http.writeJsonResponse(buffer, 405_u16, body)
|
|
}
|
|
|
|
fn __zero_std_http_request_has_json_content_type(request: Span<u8>) -> Bool {
|
|
let content_type: Maybe<Span<u8>> = __zero_std_http_request_header(request, "content-type")
|
|
if !content_type.has {
|
|
return false
|
|
}
|
|
let value: Span<u8> = std.str.trimAscii(content_type.value)
|
|
if std.mem.len(value) < 16 {
|
|
return false
|
|
}
|
|
let prefix: Span<u8> = value[..16]
|
|
if !std.str.eqlIgnoreAsciiCase(prefix, "application/json") {
|
|
return false
|
|
}
|
|
if std.mem.len(value) == 16 {
|
|
return true
|
|
}
|
|
return value[16] == 59_u8
|
|
}
|
|
|
|
fn __zero_std_http_request_json_body_within(request: Span<u8>, max: usize) -> Maybe<Span<u8>> {
|
|
let has_json: Bool = __zero_std_http_request_has_json_content_type(request)
|
|
if !has_json {
|
|
return null
|
|
}
|
|
let body: Maybe<Span<u8>> = __zero_std_http_request_body_within(request, max)
|
|
if !body.has {
|
|
return null
|
|
}
|
|
if !std.json.validateBytes(body.value) {
|
|
return null
|
|
}
|
|
return body.value
|
|
}
|
|
|
|
fn __zero_std_http_response_body_bytes(response: Span<u8>) -> Maybe<Span<u8>> {
|
|
let offset: usize = std.http.responseBodyOffset(response)
|
|
if offset > std.mem.len(response) {
|
|
return null
|
|
}
|
|
return response[offset..]
|
|
}
|
|
|
|
fn __zero_std_http_response_status(response: Span<u8>) -> Maybe<u16> {
|
|
let line_end: Maybe<usize> = __zero_std_http_first_line_end(response)
|
|
if !line_end.has || line_end.value < 12 {
|
|
return null
|
|
}
|
|
if !std.mem.eql(response[..9], "HTTP/1.1 ") && !std.mem.eql(response[..9], "HTTP/1.0 ") {
|
|
return null
|
|
}
|
|
let code: Maybe<usize> = std.parse.parseUsize(response[9..12])
|
|
if !code.has || code.value < 100_usize || code.value > 999_usize || (line_end.value > 12 && response[12] != 32_u8) {
|
|
return null
|
|
}
|
|
return code.value as u16
|
|
}
|
|
|
|
fn __zero_std_http_response_status_is(response: Span<u8>, status: u16) -> Bool {
|
|
let found: Maybe<u16> = __zero_std_http_response_status(response)
|
|
return found.has && found.value == status
|
|
}
|
|
|
|
fn __zero_std_http_response_header(response: Span<u8>, name: Span<u8>) -> Maybe<Span<u8>> {
|
|
if std.mem.len(name) == 0 {
|
|
return null
|
|
}
|
|
let body_start: Maybe<usize> = __zero_std_http_body_start(response)
|
|
if !body_start.has {
|
|
return null
|
|
}
|
|
var start: usize = std.io.nextLineStart(response, 0)
|
|
while start < body_start.value {
|
|
let line: Maybe<Span<u8>> = std.io.nextLine(response, start)
|
|
if !line.has || std.mem.len(line.value) == 0 {
|
|
return null
|
|
}
|
|
var colon: usize = 0
|
|
while colon < std.mem.len(line.value) && line.value[colon] != 58_u8 {
|
|
colon = colon + 1
|
|
}
|
|
if colon > 0 && colon < std.mem.len(line.value) {
|
|
let header_name: Span<u8> = line.value[..colon]
|
|
if std.str.eqlIgnoreAsciiCase(header_name, name) {
|
|
return std.str.trimAscii(line.value[colon + 1..])
|
|
}
|
|
}
|
|
start = std.io.nextLineStart(response, start)
|
|
}
|
|
return null
|
|
}
|
|
|
|
fn __zero_std_http_response_content_type(response: Span<u8>) -> Maybe<Span<u8>> {
|
|
let header: Maybe<Span<u8>> = __zero_std_http_response_header(response, "content-type")
|
|
if !header.has {
|
|
return null
|
|
}
|
|
let trimmed: Span<u8> = std.str.trimAscii(header.value)
|
|
var end: usize = 0
|
|
while end < std.mem.len(trimmed) && trimmed[end] != 59_u8 {
|
|
end = end + 1
|
|
}
|
|
return std.str.trimAscii(trimmed[..end])
|
|
}
|
|
|
|
fn __zero_std_http_response_redirect_location(response: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_http_response_header(response, "location")
|
|
}
|
|
|
|
fn __zero_std_http_response_body_equals(response: Span<u8>, expected: Span<u8>) -> Bool {
|
|
let body: Maybe<Span<u8>> = __zero_std_http_response_body_bytes(response)
|
|
return body.has && std.mem.eql(body.value, expected)
|
|
}
|
|
|
|
fn __zero_std_http_response_matches(response: Span<u8>, status: u16, content_type: Span<u8>, body: Span<u8>) -> Bool {
|
|
if !__zero_std_http_response_status_is(response, status) {
|
|
return false
|
|
}
|
|
if std.mem.len(content_type) > 0 {
|
|
let found_type: Maybe<Span<u8>> = __zero_std_http_response_content_type(response)
|
|
if !found_type.has || !std.str.eqlIgnoreAsciiCase(found_type.value, content_type) {
|
|
return false
|
|
}
|
|
}
|
|
return __zero_std_http_response_body_equals(response, body)
|
|
}
|
|
|
|
fn __zero_std_http_request_method_is(request: Span<u8>, method: Span<u8>) -> Bool {
|
|
let found: Maybe<Span<u8>> = __zero_std_http_request_method_name(request)
|
|
if !found.has {
|
|
return false
|
|
}
|
|
return std.mem.eql(found.value, method)
|
|
}
|
|
|
|
fn __zero_std_http_method_allowed(method: Span<u8>, allowed: Span<u8>) -> Bool {
|
|
if std.mem.len(method) == 0 {
|
|
return false
|
|
}
|
|
var start: usize = 0
|
|
while start <= std.mem.len(allowed) {
|
|
var end: usize = start
|
|
while end < std.mem.len(allowed) && allowed[end] != 44_u8 {
|
|
end = end + 1
|
|
}
|
|
let item: Span<u8> = std.str.trimAscii(allowed[start..end])
|
|
if std.mem.eql(item, "*") || std.str.eqlIgnoreAsciiCase(item, method) {
|
|
return true
|
|
}
|
|
if end == std.mem.len(allowed) {
|
|
return false
|
|
}
|
|
start = end + 1
|
|
}
|
|
return false
|
|
}
|
|
|
|
fn __zero_std_http_request_method_allowed(request: Span<u8>, allowed: Span<u8>) -> Bool {
|
|
let method: Maybe<Span<u8>> = __zero_std_http_request_method_name(request)
|
|
return method.has && __zero_std_http_method_allowed(method.value, allowed)
|
|
}
|
|
|
|
fn __zero_std_http_request_route_method_allowed(request: Span<u8>, pattern: Span<u8>, allowed: Span<u8>) -> Bool {
|
|
if !__zero_std_http_request_method_allowed(request, allowed) {
|
|
return false
|
|
}
|
|
let path: Maybe<Span<u8>> = __zero_std_http_request_path(request)
|
|
if !path.has {
|
|
return false
|
|
}
|
|
return __zero_std_http_path_matches_pattern(path.value, pattern)
|
|
}
|
|
|
|
fn __zero_std_http_request_is_get(request: Span<u8>, path: Span<u8>) -> Bool {
|
|
return __zero_std_http_request_matches(request, "GET", path)
|
|
}
|
|
|
|
fn __zero_std_http_request_is_post(request: Span<u8>, path: Span<u8>) -> Bool {
|
|
return __zero_std_http_request_matches(request, "POST", path)
|
|
}
|
|
|
|
fn __zero_std_http_request_is_put(request: Span<u8>, path: Span<u8>) -> Bool {
|
|
return __zero_std_http_request_matches(request, "PUT", path)
|
|
}
|
|
|
|
fn __zero_std_http_request_is_patch(request: Span<u8>, path: Span<u8>) -> Bool {
|
|
return __zero_std_http_request_matches(request, "PATCH", path)
|
|
}
|
|
|
|
fn __zero_std_http_request_is_delete(request: Span<u8>, path: Span<u8>) -> Bool {
|
|
return __zero_std_http_request_matches(request, "DELETE", path)
|
|
}
|
|
|
|
fn __zero_std_http_request_path_starts_with(request: Span<u8>, prefix: Span<u8>) -> Bool {
|
|
let path: Maybe<Span<u8>> = __zero_std_http_request_path(request)
|
|
if !path.has {
|
|
return false
|
|
}
|
|
return std.str.startsWith(path.value, prefix)
|
|
}
|
|
|
|
fn __zero_std_http_request_path_tail_after(request: Span<u8>, prefix: Span<u8>) -> Maybe<Span<u8>> {
|
|
let path: Maybe<Span<u8>> = __zero_std_http_request_path(request)
|
|
if !path.has {
|
|
return null
|
|
}
|
|
if !std.str.startsWith(path.value, prefix) {
|
|
return null
|
|
}
|
|
let size: usize = std.mem.len(prefix)
|
|
return std.mem.dropPrefix(path.value, size)
|
|
}
|
|
|
|
fn __zero_std_http_pattern_segment_matches(pattern: Span<u8>, segment: Span<u8>) -> Bool {
|
|
if std.mem.len(pattern) == 0 {
|
|
return false
|
|
}
|
|
if std.mem.eql(pattern, "*") {
|
|
return true
|
|
}
|
|
if pattern[0] == 58_u8 {
|
|
return std.mem.len(pattern) > 1 && std.mem.len(segment) > 0
|
|
}
|
|
return std.mem.eql(pattern, segment)
|
|
}
|
|
|
|
fn __zero_std_http_path_matches_pattern(path: Span<u8>, pattern: Span<u8>) -> Bool {
|
|
let path_count: usize = __zero_std_http_path_segment_count(path)
|
|
let pattern_count: usize = __zero_std_http_path_segment_count(pattern)
|
|
if pattern_count == 0 {
|
|
return path_count == 0
|
|
}
|
|
let last_pattern: Maybe<Span<u8>> = __zero_std_http_path_segment(pattern, pattern_count - 1)
|
|
var wildcard_tail: Bool = false
|
|
if last_pattern.has {
|
|
wildcard_tail = std.mem.eql(last_pattern.value, "*")
|
|
}
|
|
var pattern_index: usize = 0
|
|
let non_tail_limit: usize = pattern_count - 1
|
|
while pattern_index < non_tail_limit {
|
|
let pattern_segment: Maybe<Span<u8>> = __zero_std_http_path_segment(pattern, pattern_index)
|
|
if pattern_segment.has && std.mem.eql(pattern_segment.value, "*") {
|
|
return false
|
|
}
|
|
pattern_index = pattern_index + 1
|
|
}
|
|
if wildcard_tail {
|
|
if path_count < pattern_count - 1 {
|
|
return false
|
|
}
|
|
} else if path_count != pattern_count {
|
|
return false
|
|
}
|
|
var index: usize = 0
|
|
var limit: usize = pattern_count
|
|
if wildcard_tail {
|
|
limit = pattern_count - 1
|
|
}
|
|
while index < limit {
|
|
let pattern_segment: Maybe<Span<u8>> = __zero_std_http_path_segment(pattern, index)
|
|
let path_segment: Maybe<Span<u8>> = __zero_std_http_path_segment(path, index)
|
|
if !pattern_segment.has || !path_segment.has {
|
|
return false
|
|
}
|
|
if !__zero_std_http_pattern_segment_matches(pattern_segment.value, path_segment.value) {
|
|
return false
|
|
}
|
|
index = index + 1
|
|
}
|
|
return true
|
|
}
|
|
|
|
fn __zero_std_http_request_route_matches(request: Span<u8>, method: Span<u8>, pattern: Span<u8>) -> Bool {
|
|
if !__zero_std_http_request_method_is(request, method) {
|
|
return false
|
|
}
|
|
let path: Maybe<Span<u8>> = __zero_std_http_request_path(request)
|
|
if !path.has {
|
|
return false
|
|
}
|
|
return __zero_std_http_path_matches_pattern(path.value, pattern)
|
|
}
|
|
|
|
fn __zero_std_http_path_param(path: Span<u8>, pattern: Span<u8>, name: Span<u8>) -> Maybe<Span<u8>> {
|
|
if std.mem.len(name) == 0 {
|
|
return null
|
|
}
|
|
if !__zero_std_http_path_matches_pattern(path, pattern) {
|
|
return null
|
|
}
|
|
let pattern_count: usize = __zero_std_http_path_segment_count(pattern)
|
|
var index: usize = 0
|
|
while index < pattern_count {
|
|
let pattern_segment: Maybe<Span<u8>> = __zero_std_http_path_segment(pattern, index)
|
|
if pattern_segment.has && std.mem.len(pattern_segment.value) > 1 && pattern_segment.value[0] == 58_u8 {
|
|
if std.mem.eql(pattern_segment.value[1..], name) {
|
|
return __zero_std_http_path_segment(path, index)
|
|
}
|
|
}
|
|
index = index + 1
|
|
}
|
|
return null
|
|
}
|
|
|
|
fn __zero_std_http_request_path_param(request: Span<u8>, pattern: Span<u8>, name: Span<u8>) -> Maybe<Span<u8>> {
|
|
let path: Maybe<Span<u8>> = __zero_std_http_request_path(request)
|
|
if !path.has {
|
|
return null
|
|
}
|
|
return __zero_std_http_path_param(path.value, pattern, name)
|
|
}
|
|
|
|
fn __zero_std_http_request_content_length(request: Span<u8>) -> Maybe<usize> {
|
|
let header: Maybe<Span<u8>> = __zero_std_http_request_header(request, "content-length")
|
|
if !header.has {
|
|
return null
|
|
}
|
|
let trimmed: Span<u8> = std.str.trimAscii(header.value)
|
|
if std.mem.len(trimmed) == 0 {
|
|
return null
|
|
}
|
|
return std.parse.parseUsize(trimmed)
|
|
}
|
|
|
|
fn __zero_std_http_request_content_type(request: Span<u8>) -> Maybe<Span<u8>> {
|
|
let header: Maybe<Span<u8>> = __zero_std_http_request_header(request, "content-type")
|
|
if !header.has {
|
|
return null
|
|
}
|
|
let trimmed: Span<u8> = std.str.trimAscii(header.value)
|
|
var end: usize = 0
|
|
while end < std.mem.len(trimmed) && trimmed[end] != 59_u8 {
|
|
end = end + 1
|
|
}
|
|
return std.str.trimAscii(trimmed[..end])
|
|
}
|
|
|
|
fn __zero_std_http_q_value_zero(value: Span<u8>) -> Bool {
|
|
if std.mem.len(value) == 0 || value[0] != 48_u8 {
|
|
return false
|
|
}
|
|
if std.mem.len(value) == 1 {
|
|
return true
|
|
}
|
|
if value[1] != 46_u8 {
|
|
return false
|
|
}
|
|
var index: usize = 2
|
|
while index < std.mem.len(value) {
|
|
let byte: u8 = value[index]
|
|
if byte < 48_u8 || byte > 57_u8 {
|
|
return false
|
|
}
|
|
if byte != 48_u8 {
|
|
return false
|
|
}
|
|
index = index + 1
|
|
}
|
|
return true
|
|
}
|
|
|
|
fn __zero_std_http_accept_q_allows(item: Span<u8>) -> Bool {
|
|
var start: usize = 0
|
|
while start < std.mem.len(item) && item[start] != 59_u8 {
|
|
start = start + 1
|
|
}
|
|
if start >= std.mem.len(item) {
|
|
return true
|
|
}
|
|
start = start + 1
|
|
while start < std.mem.len(item) {
|
|
var end: usize = start
|
|
while end < std.mem.len(item) && item[end] != 59_u8 {
|
|
end = end + 1
|
|
}
|
|
let parameter: Span<u8> = std.str.trimAscii(item[start..end])
|
|
var eq: usize = 0
|
|
while eq < std.mem.len(parameter) && parameter[eq] != 61_u8 {
|
|
eq = eq + 1
|
|
}
|
|
if eq > 0 && eq < std.mem.len(parameter) {
|
|
let name: Span<u8> = std.str.trimAscii(parameter[..eq])
|
|
if std.str.eqlIgnoreAsciiCase(name, "q") {
|
|
let q_value: Span<u8> = std.str.trimAscii(parameter[eq + 1..])
|
|
return !__zero_std_http_q_value_zero(q_value)
|
|
}
|
|
}
|
|
if end == std.mem.len(item) {
|
|
return true
|
|
}
|
|
start = end + 1
|
|
}
|
|
return true
|
|
}
|
|
|
|
fn __zero_std_http_request_accepts(request: Span<u8>, media: Span<u8>) -> Bool {
|
|
if std.mem.len(media) == 0 {
|
|
return false
|
|
}
|
|
let header: Maybe<Span<u8>> = __zero_std_http_request_header(request, "accept")
|
|
if !header.has {
|
|
return true
|
|
}
|
|
var start: usize = 0
|
|
var exact_seen: Bool = false
|
|
var exact_allowed: Bool = false
|
|
var subtype_seen: Bool = false
|
|
var subtype_allowed: Bool = false
|
|
var wildcard_seen: Bool = false
|
|
var wildcard_allowed: Bool = false
|
|
while start <= std.mem.len(header.value) {
|
|
var end: usize = start
|
|
while end < std.mem.len(header.value) && header.value[end] != 44_u8 {
|
|
end = end + 1
|
|
}
|
|
let item: Span<u8> = std.str.trimAscii(header.value[start..end])
|
|
var value_end: usize = 0
|
|
while value_end < std.mem.len(item) && item[value_end] != 59_u8 {
|
|
value_end = value_end + 1
|
|
}
|
|
let value: Span<u8> = std.str.trimAscii(item[..value_end])
|
|
var specificity: usize = 0
|
|
if std.str.eqlIgnoreAsciiCase(value, media) {
|
|
specificity = 3
|
|
} else {
|
|
var slash: usize = 0
|
|
while slash < std.mem.len(value) && value[slash] != 47_u8 {
|
|
slash = slash + 1
|
|
}
|
|
let value_len: usize = std.mem.len(value)
|
|
if std.mem.eql(value, "*/*") {
|
|
specificity = 1
|
|
} else if slash + 2 == value_len && value[slash + 1] == 42_u8 {
|
|
if std.mem.len(media) > slash && media[slash] == 47_u8 {
|
|
if std.str.eqlIgnoreAsciiCase(value[..slash], media[..slash]) {
|
|
specificity = 2
|
|
}
|
|
}
|
|
}
|
|
}
|
|
let allowed: Bool = __zero_std_http_accept_q_allows(item)
|
|
if specificity == 3 {
|
|
exact_seen = true
|
|
if allowed {
|
|
exact_allowed = true
|
|
} else {
|
|
exact_allowed = false
|
|
}
|
|
} else if specificity == 2 {
|
|
subtype_seen = true
|
|
if allowed {
|
|
subtype_allowed = true
|
|
} else {
|
|
subtype_allowed = false
|
|
}
|
|
} else if specificity == 1 {
|
|
wildcard_seen = true
|
|
if allowed {
|
|
wildcard_allowed = true
|
|
} else {
|
|
wildcard_allowed = false
|
|
}
|
|
}
|
|
if end == std.mem.len(header.value) {
|
|
if exact_seen {
|
|
return exact_allowed
|
|
}
|
|
if subtype_seen {
|
|
return subtype_allowed
|
|
}
|
|
if wildcard_seen {
|
|
return wildcard_allowed
|
|
}
|
|
return false
|
|
}
|
|
start = end + 1
|
|
}
|
|
if exact_seen {
|
|
return exact_allowed
|
|
}
|
|
if subtype_seen {
|
|
return subtype_allowed
|
|
}
|
|
if wildcard_seen {
|
|
return wildcard_allowed
|
|
}
|
|
return false
|
|
}
|
|
|
|
fn __zero_std_http_request_accepts_json(request: Span<u8>) -> Bool {
|
|
return __zero_std_http_request_accepts(request, "application/json")
|
|
}
|
|
|
|
fn __zero_std_http_request_json_field(request: Span<u8>, name: Span<u8>, max: usize) -> Maybe<Span<u8>> {
|
|
let body: Maybe<Span<u8>> = __zero_std_http_request_json_body_within(request, max)
|
|
if !body.has {
|
|
return null
|
|
}
|
|
return std.json.field(body.value, name)
|
|
}
|
|
|
|
fn __zero_std_http_write_json_unauthorized(buffer: MutSpan<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return std.http.writeJsonResponse(buffer, 401_u16, body)
|
|
}
|
|
|
|
fn __zero_std_http_write_json_forbidden(buffer: MutSpan<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return std.http.writeJsonResponse(buffer, 403_u16, body)
|
|
}
|
|
|
|
fn __zero_std_http_write_json_conflict(buffer: MutSpan<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return std.http.writeJsonResponse(buffer, 409_u16, body)
|
|
}
|
|
|
|
fn __zero_std_http_write_json_unprocessable(buffer: MutSpan<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return std.http.writeJsonResponse(buffer, 422_u16, body)
|
|
}
|
|
|
|
fn __zero_std_http_write_json_too_many_requests(buffer: MutSpan<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return std.http.writeJsonResponse(buffer, 429_u16, body)
|
|
}
|
|
|
|
fn __zero_std_http_write_json_internal_server_error(buffer: MutSpan<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return std.http.writeJsonResponse(buffer, 500_u16, body)
|
|
}
|
|
|
|
fn __zero_std_http_write_no_content(buffer: MutSpan<u8>) -> Maybe<Span<u8>> {
|
|
return std.http.writeResponse(buffer, 204_u16, "")
|
|
}
|
|
|
|
fn __zero_std_http_path_segment_count(path: Span<u8>) -> usize {
|
|
var count: usize = 0
|
|
var index: usize = 0
|
|
while index < std.mem.len(path) {
|
|
while index < std.mem.len(path) && path[index] == 47_u8 {
|
|
index = index + 1
|
|
}
|
|
if index < std.mem.len(path) {
|
|
count = count + 1
|
|
while index < std.mem.len(path) && path[index] != 47_u8 {
|
|
index = index + 1
|
|
}
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
fn __zero_std_http_path_segment(path: Span<u8>, index: usize) -> Maybe<Span<u8>> {
|
|
var current: usize = 0
|
|
var start: usize = 0
|
|
while start < std.mem.len(path) {
|
|
while start < std.mem.len(path) && path[start] == 47_u8 {
|
|
start = start + 1
|
|
}
|
|
if start < std.mem.len(path) {
|
|
var end: usize = start
|
|
while end < std.mem.len(path) && path[end] != 47_u8 {
|
|
end = end + 1
|
|
}
|
|
if current == index {
|
|
return path[start..end]
|
|
}
|
|
current = current + 1
|
|
start = end
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
fn __zero_std_http_request_path_segment_count(request: Span<u8>) -> usize {
|
|
let path: Maybe<Span<u8>> = __zero_std_http_request_path(request)
|
|
if !path.has {
|
|
return 0
|
|
}
|
|
return __zero_std_http_path_segment_count(path.value)
|
|
}
|
|
|
|
fn __zero_std_http_request_path_segment(request: Span<u8>, index: usize) -> Maybe<Span<u8>> {
|
|
let path: Maybe<Span<u8>> = __zero_std_http_request_path(request)
|
|
if !path.has {
|
|
return null
|
|
}
|
|
return __zero_std_http_path_segment(path.value, index)
|
|
}
|
|
|
|
fn __zero_std_http_request_is_head(request: Span<u8>, path: Span<u8>) -> Bool {
|
|
return __zero_std_http_request_matches(request, "HEAD", path)
|
|
}
|
|
|
|
fn __zero_std_http_request_is_options(request: Span<u8>, path: Span<u8>) -> Bool {
|
|
return __zero_std_http_request_matches(request, "OPTIONS", path)
|
|
}
|
|
|
|
fn __zero_std_http_write_cors_preflight(buffer: MutSpan<u8>, allow_origin: Span<u8>, allow_methods: Span<u8>, allow_headers: Span<u8>) -> Maybe<Span<u8>> {
|
|
var offset: usize = 0
|
|
let status: Maybe<usize> = __zero_std_http_write(buffer, offset, "HTTP/1.1 204 No Content\r\nconnection: close\r\n")
|
|
if !status.has {
|
|
return null
|
|
}
|
|
offset = status.value
|
|
let origin_label: Maybe<usize> = __zero_std_http_write(buffer, offset, "access-control-allow-origin: ")
|
|
if !origin_label.has {
|
|
return null
|
|
}
|
|
offset = origin_label.value
|
|
let origin_value: Maybe<usize> = __zero_std_http_write(buffer, offset, allow_origin)
|
|
if !origin_value.has {
|
|
return null
|
|
}
|
|
offset = origin_value.value
|
|
let origin_line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !origin_line.has {
|
|
return null
|
|
}
|
|
offset = origin_line.value
|
|
let methods_label: Maybe<usize> = __zero_std_http_write(buffer, offset, "access-control-allow-methods: ")
|
|
if !methods_label.has {
|
|
return null
|
|
}
|
|
offset = methods_label.value
|
|
let methods_value: Maybe<usize> = __zero_std_http_write(buffer, offset, allow_methods)
|
|
if !methods_value.has {
|
|
return null
|
|
}
|
|
offset = methods_value.value
|
|
let methods_line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !methods_line.has {
|
|
return null
|
|
}
|
|
offset = methods_line.value
|
|
let headers_label: Maybe<usize> = __zero_std_http_write(buffer, offset, "access-control-allow-headers: ")
|
|
if !headers_label.has {
|
|
return null
|
|
}
|
|
offset = headers_label.value
|
|
let headers_value: Maybe<usize> = __zero_std_http_write(buffer, offset, allow_headers)
|
|
if !headers_value.has {
|
|
return null
|
|
}
|
|
offset = headers_value.value
|
|
let headers_line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !headers_line.has {
|
|
return null
|
|
}
|
|
offset = headers_line.value
|
|
let length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, 0_usize)
|
|
if !length.has {
|
|
return null
|
|
}
|
|
offset = length.value
|
|
let blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !blank.has {
|
|
return null
|
|
}
|
|
return buffer[..blank.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_cors_json_response(buffer: MutSpan<u8>, status_line: Span<u8>, body: Span<u8>, allow_origin: Span<u8>) -> Maybe<Span<u8>> {
|
|
var offset: usize = 0
|
|
let prefix: Maybe<usize> = __zero_std_http_write(buffer, offset, "HTTP/1.1 ")
|
|
if !prefix.has {
|
|
return null
|
|
}
|
|
offset = prefix.value
|
|
let status: Maybe<usize> = __zero_std_http_write(buffer, offset, status_line)
|
|
if !status.has {
|
|
return null
|
|
}
|
|
offset = status.value
|
|
let content_type: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\ncontent-type: application/json\r\nconnection: close\r\naccess-control-allow-origin: ")
|
|
if !content_type.has {
|
|
return null
|
|
}
|
|
offset = content_type.value
|
|
let origin_value: Maybe<usize> = __zero_std_http_write(buffer, offset, allow_origin)
|
|
if !origin_value.has {
|
|
return null
|
|
}
|
|
offset = origin_value.value
|
|
let origin_line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !origin_line.has {
|
|
return null
|
|
}
|
|
offset = origin_line.value
|
|
let body_len: usize = std.mem.len(body)
|
|
let length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, body_len)
|
|
if !length.has {
|
|
return null
|
|
}
|
|
offset = length.value
|
|
let blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !blank.has {
|
|
return null
|
|
}
|
|
offset = blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_request_bearer_token(request: Span<u8>) -> Maybe<Span<u8>> {
|
|
let authorization: Maybe<Span<u8>> = std.http.requestHeader(request, "authorization")
|
|
if !authorization.has {
|
|
return null
|
|
}
|
|
let value: Span<u8> = std.str.trimAscii(authorization.value)
|
|
if std.mem.len(value) <= 7 {
|
|
return null
|
|
}
|
|
let scheme: Span<u8> = value[..7]
|
|
if !std.str.eqlIgnoreAsciiCase(scheme, "Bearer ") {
|
|
return null
|
|
}
|
|
let token: Span<u8> = std.str.trimAscii(value[7..])
|
|
if std.mem.len(token) == 0 {
|
|
return null
|
|
}
|
|
return token
|
|
}
|
|
|
|
fn __zero_std_http_request_cookie(request: Span<u8>, name: Span<u8>) -> Maybe<Span<u8>> {
|
|
if std.mem.len(name) == 0 {
|
|
return null
|
|
}
|
|
let cookie: Maybe<Span<u8>> = std.http.requestHeader(request, "cookie")
|
|
if !cookie.has {
|
|
return null
|
|
}
|
|
var start: usize = 0
|
|
while start <= std.mem.len(cookie.value) {
|
|
var end: usize = start
|
|
while end < std.mem.len(cookie.value) && cookie.value[end] != 59_u8 {
|
|
end = end + 1
|
|
}
|
|
var eq: usize = start
|
|
while eq < end && cookie.value[eq] != 61_u8 {
|
|
eq = eq + 1
|
|
}
|
|
let cookie_name: Span<u8> = std.str.trimAscii(cookie.value[start..eq])
|
|
if std.mem.eql(cookie_name, name) {
|
|
if eq < end {
|
|
let value_start: usize = eq + 1
|
|
return std.str.trimAscii(cookie.value[value_start..end])
|
|
}
|
|
return cookie.value[end..end]
|
|
}
|
|
if end == std.mem.len(cookie.value) {
|
|
return null
|
|
}
|
|
start = end + 1
|
|
}
|
|
return null
|
|
}
|
|
|
|
fn __zero_std_http_error_code_valid(code: Span<u8>) -> Bool {
|
|
if std.mem.len(code) == 0 {
|
|
return false
|
|
}
|
|
var index: usize = 0
|
|
while index < std.mem.len(code) {
|
|
let byte: u8 = code[index]
|
|
if !(byte >= 97_u8 && byte <= 122_u8 || byte >= 48_u8 && byte <= 57_u8 || byte == 45_u8 || byte == 95_u8) {
|
|
return false
|
|
}
|
|
index = index + 1
|
|
}
|
|
return true
|
|
}
|
|
|
|
fn __zero_std_http_write_json_error(buffer: MutSpan<u8>, status: u16, code: Span<u8>) -> Maybe<Span<u8>> {
|
|
if !__zero_std_http_error_code_valid(code) {
|
|
return null
|
|
}
|
|
let body_len: usize = 12 + std.mem.len(code)
|
|
let status_value: usize = status as usize
|
|
var offset: usize = 0
|
|
let prefix: Maybe<usize> = __zero_std_http_write(buffer, offset, "HTTP/1.1 ")
|
|
if !prefix.has {
|
|
return null
|
|
}
|
|
offset = prefix.value
|
|
let status_text: Maybe<usize> = __zero_std_http_write_usize(buffer, offset, status_value)
|
|
if !status_text.has {
|
|
return null
|
|
}
|
|
offset = status_text.value
|
|
let space: Maybe<usize> = __zero_std_http_write(buffer, offset, " ")
|
|
if !space.has {
|
|
return null
|
|
}
|
|
offset = space.value
|
|
let reason_text: String = __zero_std_http_status_reason(status)
|
|
let reason_span: Span<u8> = std.mem.span(reason_text)
|
|
let reason: Maybe<usize> = __zero_std_http_write(buffer, offset, reason_span)
|
|
if !reason.has {
|
|
return null
|
|
}
|
|
offset = reason.value
|
|
let line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\ncontent-type: application/json\r\nconnection: close\r\n")
|
|
if !line.has {
|
|
return null
|
|
}
|
|
offset = line.value
|
|
let length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, body_len)
|
|
if !length.has {
|
|
return null
|
|
}
|
|
offset = length.value
|
|
let blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !blank.has {
|
|
return null
|
|
}
|
|
offset = blank.value
|
|
let body_prefix: Maybe<usize> = __zero_std_http_write(buffer, offset, "{\"error\":\"")
|
|
if !body_prefix.has {
|
|
return null
|
|
}
|
|
offset = body_prefix.value
|
|
let wrote_code: Maybe<usize> = __zero_std_http_write(buffer, offset, code)
|
|
if !wrote_code.has {
|
|
return null
|
|
}
|
|
offset = wrote_code.value
|
|
let body_suffix: Maybe<usize> = __zero_std_http_write(buffer, offset, "\"}")
|
|
if !body_suffix.has {
|
|
return null
|
|
}
|
|
return buffer[..body_suffix.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_typed_response(buffer: MutSpan<u8>, status: u16, content_type: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
var offset: usize = 0
|
|
let prefix: Maybe<usize> = __zero_std_http_write(buffer, offset, "HTTP/1.1 ")
|
|
if !prefix.has {
|
|
return null
|
|
}
|
|
offset = prefix.value
|
|
let status_value: usize = status as usize
|
|
let code: Maybe<usize> = __zero_std_http_write_usize(buffer, offset, status_value)
|
|
if !code.has {
|
|
return null
|
|
}
|
|
offset = code.value
|
|
let space: Maybe<usize> = __zero_std_http_write(buffer, offset, " ")
|
|
if !space.has {
|
|
return null
|
|
}
|
|
offset = space.value
|
|
let reason_text: String = __zero_std_http_status_reason(status)
|
|
let reason_span: Span<u8> = std.mem.span(reason_text)
|
|
let reason: Maybe<usize> = __zero_std_http_write(buffer, offset, reason_span)
|
|
if !reason.has {
|
|
return null
|
|
}
|
|
offset = reason.value
|
|
let header: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\ncontent-type: ")
|
|
if !header.has {
|
|
return null
|
|
}
|
|
offset = header.value
|
|
let header_value: Maybe<usize> = __zero_std_http_write(buffer, offset, content_type)
|
|
if !header_value.has {
|
|
return null
|
|
}
|
|
offset = header_value.value
|
|
let line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\nconnection: close\r\n")
|
|
if !line.has {
|
|
return null
|
|
}
|
|
offset = line.value
|
|
let body_len: usize = std.mem.len(body)
|
|
let length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, body_len)
|
|
if !length.has {
|
|
return null
|
|
}
|
|
offset = length.value
|
|
let blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !blank.has {
|
|
return null
|
|
}
|
|
offset = blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_text_response(buffer: MutSpan<u8>, status: u16, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_http_write_typed_response(buffer, status, "text/plain; charset=utf-8", body)
|
|
}
|
|
|
|
fn __zero_std_http_write_html_response(buffer: MutSpan<u8>, status: u16, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_http_write_typed_response(buffer, status, "text/html; charset=utf-8", body)
|
|
}
|
|
|
|
fn __zero_std_http_header_name_safe(name: Span<u8>) -> Bool {
|
|
return __zero_std_http_method_valid(name)
|
|
}
|
|
|
|
fn __zero_std_http_header_line_safe(line: Span<u8>) -> Bool {
|
|
var index: usize = 0
|
|
while index < std.mem.len(line) {
|
|
if line[index] == 10_u8 || line[index] == 13_u8 {
|
|
return false
|
|
}
|
|
index = index + 1
|
|
}
|
|
var colon: usize = 0
|
|
while colon < std.mem.len(line) && line[colon] != 58_u8 {
|
|
colon = colon + 1
|
|
}
|
|
if colon == 0 || colon >= std.mem.len(line) {
|
|
return false
|
|
}
|
|
let header_name: Span<u8> = line[..colon]
|
|
let header_value: Span<u8> = std.str.trimAscii(line[colon + 1..])
|
|
return __zero_std_http_header_name_safe(header_name) && __zero_std_http_header_value_safe(header_value)
|
|
}
|
|
|
|
fn __zero_std_http_header_block_safe(headers: Span<u8>) -> Bool {
|
|
if std.mem.len(headers) == 0 {
|
|
return false
|
|
}
|
|
var start: usize = 0
|
|
while start < std.mem.len(headers) {
|
|
var end: usize = start
|
|
while end < std.mem.len(headers) && headers[end] != 10_u8 {
|
|
end = end + 1
|
|
}
|
|
var line_end: usize = end
|
|
if line_end > start && headers[line_end - 1] == 13_u8 {
|
|
line_end = line_end - 1
|
|
}
|
|
if line_end == start || !__zero_std_http_header_line_safe(headers[start..line_end]) {
|
|
return false
|
|
}
|
|
if end == std.mem.len(headers) {
|
|
return true
|
|
}
|
|
start = end + 1
|
|
if start >= std.mem.len(headers) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
fn __zero_std_http_write_header_block(buffer: MutSpan<u8>, offset: usize, headers: Span<u8>) -> Maybe<usize> {
|
|
if !__zero_std_http_header_block_safe(headers) {
|
|
return null
|
|
}
|
|
var current: usize = offset
|
|
var start: usize = 0
|
|
while start < std.mem.len(headers) {
|
|
var end: usize = start
|
|
while end < std.mem.len(headers) && headers[end] != 10_u8 {
|
|
end = end + 1
|
|
}
|
|
var line_end: usize = end
|
|
if line_end > start && headers[line_end - 1] == 13_u8 {
|
|
line_end = line_end - 1
|
|
}
|
|
let wrote_header: Maybe<usize> = __zero_std_http_write(buffer, current, headers[start..line_end])
|
|
if !wrote_header.has {
|
|
return null
|
|
}
|
|
current = wrote_header.value
|
|
let wrote_line: Maybe<usize> = __zero_std_http_write(buffer, current, "\r\n")
|
|
if !wrote_line.has {
|
|
return null
|
|
}
|
|
current = wrote_line.value
|
|
if end == std.mem.len(headers) {
|
|
return current
|
|
}
|
|
start = end + 1
|
|
}
|
|
return current
|
|
}
|
|
|
|
fn __zero_std_http_write_response_with_header(buffer: MutSpan<u8>, status: u16, header_line: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
if !__zero_std_http_header_line_safe(header_line) {
|
|
return null
|
|
}
|
|
var header_colon: usize = 0
|
|
while header_colon < std.mem.len(header_line) && header_line[header_colon] != 58_u8 {
|
|
header_colon = header_colon + 1
|
|
}
|
|
let header_name: Span<u8> = header_line[..header_colon]
|
|
if std.str.eqlIgnoreAsciiCase(header_name, "content-length") || (std.str.eqlIgnoreAsciiCase(header_name, "transfer-encoding") || std.str.eqlIgnoreAsciiCase(header_name, "connection")) {
|
|
return null
|
|
}
|
|
var offset: usize = 0
|
|
let prefix: Maybe<usize> = __zero_std_http_write(buffer, offset, "HTTP/1.1 ")
|
|
if !prefix.has {
|
|
return null
|
|
}
|
|
offset = prefix.value
|
|
let status_value: usize = status as usize
|
|
let code: Maybe<usize> = __zero_std_http_write_usize(buffer, offset, status_value)
|
|
if !code.has {
|
|
return null
|
|
}
|
|
offset = code.value
|
|
let space: Maybe<usize> = __zero_std_http_write(buffer, offset, " ")
|
|
if !space.has {
|
|
return null
|
|
}
|
|
offset = space.value
|
|
let reason_text: String = __zero_std_http_status_reason(status)
|
|
let reason: Maybe<usize> = __zero_std_http_write(buffer, offset, std.mem.span(reason_text))
|
|
if !reason.has {
|
|
return null
|
|
}
|
|
offset = reason.value
|
|
let connection: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\nconnection: close\r\n")
|
|
if !connection.has {
|
|
return null
|
|
}
|
|
offset = connection.value
|
|
let header_written: Maybe<usize> = __zero_std_http_write(buffer, offset, header_line)
|
|
if !header_written.has {
|
|
return null
|
|
}
|
|
offset = header_written.value
|
|
let header_end: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !header_end.has {
|
|
return null
|
|
}
|
|
offset = header_end.value
|
|
let length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, std.mem.len(body))
|
|
if !length.has {
|
|
return null
|
|
}
|
|
offset = length.value
|
|
let blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !blank.has {
|
|
return null
|
|
}
|
|
offset = blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_response_with_headers(buffer: MutSpan<u8>, status: u16, headers: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
if !__zero_std_http_header_block_safe(headers) {
|
|
return null
|
|
}
|
|
var header_start: usize = 0
|
|
while header_start < std.mem.len(headers) {
|
|
var header_end: usize = header_start
|
|
while header_end < std.mem.len(headers) && headers[header_end] != 10_u8 {
|
|
header_end = header_end + 1
|
|
}
|
|
var header_line_end: usize = header_end
|
|
if header_line_end > header_start && headers[header_line_end - 1] == 13_u8 {
|
|
header_line_end = header_line_end - 1
|
|
}
|
|
var header_colon: usize = header_start
|
|
while header_colon < header_line_end && headers[header_colon] != 58_u8 {
|
|
header_colon = header_colon + 1
|
|
}
|
|
let header_name: Span<u8> = headers[header_start..header_colon]
|
|
if std.str.eqlIgnoreAsciiCase(header_name, "content-length") || (std.str.eqlIgnoreAsciiCase(header_name, "transfer-encoding") || std.str.eqlIgnoreAsciiCase(header_name, "connection")) {
|
|
return null
|
|
}
|
|
if header_end == std.mem.len(headers) {
|
|
header_start = std.mem.len(headers)
|
|
} else {
|
|
header_start = header_end + 1
|
|
}
|
|
}
|
|
var offset: usize = 0
|
|
let prefix: Maybe<usize> = __zero_std_http_write(buffer, offset, "HTTP/1.1 ")
|
|
if !prefix.has {
|
|
return null
|
|
}
|
|
offset = prefix.value
|
|
let status_value: usize = status as usize
|
|
let code: Maybe<usize> = __zero_std_http_write_usize(buffer, offset, status_value)
|
|
if !code.has {
|
|
return null
|
|
}
|
|
offset = code.value
|
|
let space: Maybe<usize> = __zero_std_http_write(buffer, offset, " ")
|
|
if !space.has {
|
|
return null
|
|
}
|
|
offset = space.value
|
|
let reason_text: String = __zero_std_http_status_reason(status)
|
|
let reason: Maybe<usize> = __zero_std_http_write(buffer, offset, std.mem.span(reason_text))
|
|
if !reason.has {
|
|
return null
|
|
}
|
|
offset = reason.value
|
|
let connection: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\nconnection: close\r\n")
|
|
if !connection.has {
|
|
return null
|
|
}
|
|
offset = connection.value
|
|
let headers_written: Maybe<usize> = __zero_std_http_write_header_block(buffer, offset, headers)
|
|
if !headers_written.has {
|
|
return null
|
|
}
|
|
offset = headers_written.value
|
|
let length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, std.mem.len(body))
|
|
if !length.has {
|
|
return null
|
|
}
|
|
offset = length.value
|
|
let blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !blank.has {
|
|
return null
|
|
}
|
|
offset = blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_json_response_with_header(buffer: MutSpan<u8>, status: u16, header_line: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
if !__zero_std_http_header_line_safe(header_line) {
|
|
return null
|
|
}
|
|
var header_colon: usize = 0
|
|
while header_colon < std.mem.len(header_line) && header_line[header_colon] != 58_u8 {
|
|
header_colon = header_colon + 1
|
|
}
|
|
let header_name: Span<u8> = header_line[..header_colon]
|
|
if std.str.eqlIgnoreAsciiCase(header_name, "content-length") || (std.str.eqlIgnoreAsciiCase(header_name, "transfer-encoding") || (std.str.eqlIgnoreAsciiCase(header_name, "content-type") || std.str.eqlIgnoreAsciiCase(header_name, "connection"))) {
|
|
return null
|
|
}
|
|
var offset: usize = 0
|
|
let prefix: Maybe<usize> = __zero_std_http_write(buffer, offset, "HTTP/1.1 ")
|
|
if !prefix.has {
|
|
return null
|
|
}
|
|
offset = prefix.value
|
|
let status_value: usize = status as usize
|
|
let code: Maybe<usize> = __zero_std_http_write_usize(buffer, offset, status_value)
|
|
if !code.has {
|
|
return null
|
|
}
|
|
offset = code.value
|
|
let space: Maybe<usize> = __zero_std_http_write(buffer, offset, " ")
|
|
if !space.has {
|
|
return null
|
|
}
|
|
offset = space.value
|
|
let reason_text: String = __zero_std_http_status_reason(status)
|
|
let reason: Maybe<usize> = __zero_std_http_write(buffer, offset, std.mem.span(reason_text))
|
|
if !reason.has {
|
|
return null
|
|
}
|
|
offset = reason.value
|
|
let fixed_headers: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\ncontent-type: application/json\r\nconnection: close\r\n")
|
|
if !fixed_headers.has {
|
|
return null
|
|
}
|
|
offset = fixed_headers.value
|
|
let header_written: Maybe<usize> = __zero_std_http_write(buffer, offset, header_line)
|
|
if !header_written.has {
|
|
return null
|
|
}
|
|
offset = header_written.value
|
|
let header_end: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !header_end.has {
|
|
return null
|
|
}
|
|
offset = header_end.value
|
|
let length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, std.mem.len(body))
|
|
if !length.has {
|
|
return null
|
|
}
|
|
offset = length.value
|
|
let blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !blank.has {
|
|
return null
|
|
}
|
|
offset = blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_json_response_with_headers(buffer: MutSpan<u8>, status: u16, headers: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
if !__zero_std_http_header_block_safe(headers) {
|
|
return null
|
|
}
|
|
var header_start: usize = 0
|
|
while header_start < std.mem.len(headers) {
|
|
var header_end: usize = header_start
|
|
while header_end < std.mem.len(headers) && headers[header_end] != 10_u8 {
|
|
header_end = header_end + 1
|
|
}
|
|
var header_line_end: usize = header_end
|
|
if header_line_end > header_start && headers[header_line_end - 1] == 13_u8 {
|
|
header_line_end = header_line_end - 1
|
|
}
|
|
var header_colon: usize = header_start
|
|
while header_colon < header_line_end && headers[header_colon] != 58_u8 {
|
|
header_colon = header_colon + 1
|
|
}
|
|
let header_name: Span<u8> = headers[header_start..header_colon]
|
|
if std.str.eqlIgnoreAsciiCase(header_name, "content-length") || (std.str.eqlIgnoreAsciiCase(header_name, "transfer-encoding") || (std.str.eqlIgnoreAsciiCase(header_name, "content-type") || std.str.eqlIgnoreAsciiCase(header_name, "connection"))) {
|
|
return null
|
|
}
|
|
if header_end == std.mem.len(headers) {
|
|
header_start = std.mem.len(headers)
|
|
} else {
|
|
header_start = header_end + 1
|
|
}
|
|
}
|
|
var offset: usize = 0
|
|
let prefix: Maybe<usize> = __zero_std_http_write(buffer, offset, "HTTP/1.1 ")
|
|
if !prefix.has {
|
|
return null
|
|
}
|
|
offset = prefix.value
|
|
let status_value: usize = status as usize
|
|
let code: Maybe<usize> = __zero_std_http_write_usize(buffer, offset, status_value)
|
|
if !code.has {
|
|
return null
|
|
}
|
|
offset = code.value
|
|
let space: Maybe<usize> = __zero_std_http_write(buffer, offset, " ")
|
|
if !space.has {
|
|
return null
|
|
}
|
|
offset = space.value
|
|
let reason_text: String = __zero_std_http_status_reason(status)
|
|
let reason: Maybe<usize> = __zero_std_http_write(buffer, offset, std.mem.span(reason_text))
|
|
if !reason.has {
|
|
return null
|
|
}
|
|
offset = reason.value
|
|
let fixed_headers: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\ncontent-type: application/json\r\nconnection: close\r\n")
|
|
if !fixed_headers.has {
|
|
return null
|
|
}
|
|
offset = fixed_headers.value
|
|
let headers_written: Maybe<usize> = __zero_std_http_write_header_block(buffer, offset, headers)
|
|
if !headers_written.has {
|
|
return null
|
|
}
|
|
offset = headers_written.value
|
|
let length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, std.mem.len(body))
|
|
if !length.has {
|
|
return null
|
|
}
|
|
offset = length.value
|
|
let blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !blank.has {
|
|
return null
|
|
}
|
|
offset = blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_cookie_value_safe(value: Span<u8>) -> Bool {
|
|
var index: usize = 0
|
|
while index < std.mem.len(value) {
|
|
let byte: u8 = value[index]
|
|
if byte <= 32_u8 || byte == 34_u8 || byte == 44_u8 || byte == 59_u8 || byte == 92_u8 || byte == 127_u8 {
|
|
return false
|
|
}
|
|
index = index + 1
|
|
}
|
|
return true
|
|
}
|
|
|
|
fn __zero_std_http_write_json_response_with_cookie(buffer: MutSpan<u8>, status: u16, cookie: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
if !__zero_std_http_header_value_safe(cookie) {
|
|
return null
|
|
}
|
|
var offset: usize = 0
|
|
let prefix: Maybe<usize> = __zero_std_http_write(buffer, offset, "HTTP/1.1 ")
|
|
if !prefix.has {
|
|
return null
|
|
}
|
|
offset = prefix.value
|
|
let status_value: usize = status as usize
|
|
let code: Maybe<usize> = __zero_std_http_write_usize(buffer, offset, status_value)
|
|
if !code.has {
|
|
return null
|
|
}
|
|
offset = code.value
|
|
let space: Maybe<usize> = __zero_std_http_write(buffer, offset, " ")
|
|
if !space.has {
|
|
return null
|
|
}
|
|
offset = space.value
|
|
let reason_text: String = __zero_std_http_status_reason(status)
|
|
let reason: Maybe<usize> = __zero_std_http_write(buffer, offset, std.mem.span(reason_text))
|
|
if !reason.has {
|
|
return null
|
|
}
|
|
offset = reason.value
|
|
let fixed_headers: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\ncontent-type: application/json\r\nconnection: close\r\nset-cookie: ")
|
|
if !fixed_headers.has {
|
|
return null
|
|
}
|
|
offset = fixed_headers.value
|
|
let cookie_value: Maybe<usize> = __zero_std_http_write(buffer, offset, cookie)
|
|
if !cookie_value.has {
|
|
return null
|
|
}
|
|
offset = cookie_value.value
|
|
let cookie_end: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !cookie_end.has {
|
|
return null
|
|
}
|
|
offset = cookie_end.value
|
|
let length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, std.mem.len(body))
|
|
if !length.has {
|
|
return null
|
|
}
|
|
offset = length.value
|
|
let blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !blank.has {
|
|
return null
|
|
}
|
|
offset = blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_request_with_header(buffer: MutSpan<u8>, start_line: Span<u8>, header_line: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
if !__zero_std_http_start_line_valid(start_line) || !__zero_std_http_header_line_safe(header_line) {
|
|
return null
|
|
}
|
|
var header_colon: usize = 0
|
|
while header_colon < std.mem.len(header_line) && header_line[header_colon] != 58_u8 {
|
|
header_colon = header_colon + 1
|
|
}
|
|
let header_name: Span<u8> = header_line[..header_colon]
|
|
if std.str.eqlIgnoreAsciiCase(header_name, "content-length") || std.str.eqlIgnoreAsciiCase(header_name, "transfer-encoding") {
|
|
return null
|
|
}
|
|
var offset: usize = 0
|
|
let wrote_line_text: Maybe<usize> = __zero_std_http_write(buffer, offset, start_line)
|
|
if !wrote_line_text.has {
|
|
return null
|
|
}
|
|
offset = wrote_line_text.value
|
|
let wrote_line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !wrote_line.has {
|
|
return null
|
|
}
|
|
offset = wrote_line.value
|
|
let header_written: Maybe<usize> = __zero_std_http_write(buffer, offset, header_line)
|
|
if !header_written.has {
|
|
return null
|
|
}
|
|
offset = header_written.value
|
|
let header_end: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !header_end.has {
|
|
return null
|
|
}
|
|
offset = header_end.value
|
|
if std.mem.len(body) > 0 {
|
|
let wrote_length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, std.mem.len(body))
|
|
if !wrote_length.has {
|
|
return null
|
|
}
|
|
offset = wrote_length.value
|
|
}
|
|
let wrote_blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !wrote_blank.has {
|
|
return null
|
|
}
|
|
offset = wrote_blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_request_with_headers(buffer: MutSpan<u8>, start_line: Span<u8>, headers: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
if !__zero_std_http_start_line_valid(start_line) || !__zero_std_http_header_block_safe(headers) {
|
|
return null
|
|
}
|
|
var header_start: usize = 0
|
|
while header_start < std.mem.len(headers) {
|
|
var header_end: usize = header_start
|
|
while header_end < std.mem.len(headers) && headers[header_end] != 10_u8 {
|
|
header_end = header_end + 1
|
|
}
|
|
var header_line_end: usize = header_end
|
|
if header_line_end > header_start && headers[header_line_end - 1] == 13_u8 {
|
|
header_line_end = header_line_end - 1
|
|
}
|
|
var header_colon: usize = header_start
|
|
while header_colon < header_line_end && headers[header_colon] != 58_u8 {
|
|
header_colon = header_colon + 1
|
|
}
|
|
let header_name: Span<u8> = headers[header_start..header_colon]
|
|
if std.str.eqlIgnoreAsciiCase(header_name, "content-length") || std.str.eqlIgnoreAsciiCase(header_name, "transfer-encoding") {
|
|
return null
|
|
}
|
|
if header_end == std.mem.len(headers) {
|
|
header_start = std.mem.len(headers)
|
|
} else {
|
|
header_start = header_end + 1
|
|
}
|
|
}
|
|
var offset: usize = 0
|
|
let wrote_line_text: Maybe<usize> = __zero_std_http_write(buffer, offset, start_line)
|
|
if !wrote_line_text.has {
|
|
return null
|
|
}
|
|
offset = wrote_line_text.value
|
|
let wrote_line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !wrote_line.has {
|
|
return null
|
|
}
|
|
offset = wrote_line.value
|
|
let headers_written: Maybe<usize> = __zero_std_http_write_header_block(buffer, offset, headers)
|
|
if !headers_written.has {
|
|
return null
|
|
}
|
|
offset = headers_written.value
|
|
if std.mem.len(body) > 0 {
|
|
let wrote_length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, std.mem.len(body))
|
|
if !wrote_length.has {
|
|
return null
|
|
}
|
|
offset = wrote_length.value
|
|
}
|
|
let wrote_blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !wrote_blank.has {
|
|
return null
|
|
}
|
|
offset = wrote_blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_json_request_with_header(buffer: MutSpan<u8>, start_line: Span<u8>, header_line: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
if !__zero_std_http_start_line_valid(start_line) || !__zero_std_http_header_line_safe(header_line) {
|
|
return null
|
|
}
|
|
var header_colon: usize = 0
|
|
while header_colon < std.mem.len(header_line) && header_line[header_colon] != 58_u8 {
|
|
header_colon = header_colon + 1
|
|
}
|
|
let header_name: Span<u8> = header_line[..header_colon]
|
|
if std.str.eqlIgnoreAsciiCase(header_name, "content-length") || (std.str.eqlIgnoreAsciiCase(header_name, "transfer-encoding") || std.str.eqlIgnoreAsciiCase(header_name, "content-type")) {
|
|
return null
|
|
}
|
|
var offset: usize = 0
|
|
let wrote_line_text: Maybe<usize> = __zero_std_http_write(buffer, offset, start_line)
|
|
if !wrote_line_text.has {
|
|
return null
|
|
}
|
|
offset = wrote_line_text.value
|
|
let wrote_line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\ncontent-type: application/json\r\n")
|
|
if !wrote_line.has {
|
|
return null
|
|
}
|
|
offset = wrote_line.value
|
|
let header_written: Maybe<usize> = __zero_std_http_write(buffer, offset, header_line)
|
|
if !header_written.has {
|
|
return null
|
|
}
|
|
offset = header_written.value
|
|
let header_end: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !header_end.has {
|
|
return null
|
|
}
|
|
offset = header_end.value
|
|
let wrote_length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, std.mem.len(body))
|
|
if !wrote_length.has {
|
|
return null
|
|
}
|
|
offset = wrote_length.value
|
|
let wrote_blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !wrote_blank.has {
|
|
return null
|
|
}
|
|
offset = wrote_blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_json_request_with_headers(buffer: MutSpan<u8>, start_line: Span<u8>, headers: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
if !__zero_std_http_start_line_valid(start_line) || !__zero_std_http_header_block_safe(headers) {
|
|
return null
|
|
}
|
|
var header_start: usize = 0
|
|
while header_start < std.mem.len(headers) {
|
|
var header_end: usize = header_start
|
|
while header_end < std.mem.len(headers) && headers[header_end] != 10_u8 {
|
|
header_end = header_end + 1
|
|
}
|
|
var header_line_end: usize = header_end
|
|
if header_line_end > header_start && headers[header_line_end - 1] == 13_u8 {
|
|
header_line_end = header_line_end - 1
|
|
}
|
|
var header_colon: usize = header_start
|
|
while header_colon < header_line_end && headers[header_colon] != 58_u8 {
|
|
header_colon = header_colon + 1
|
|
}
|
|
let header_name: Span<u8> = headers[header_start..header_colon]
|
|
if std.str.eqlIgnoreAsciiCase(header_name, "content-length") || (std.str.eqlIgnoreAsciiCase(header_name, "transfer-encoding") || std.str.eqlIgnoreAsciiCase(header_name, "content-type")) {
|
|
return null
|
|
}
|
|
if header_end == std.mem.len(headers) {
|
|
header_start = std.mem.len(headers)
|
|
} else {
|
|
header_start = header_end + 1
|
|
}
|
|
}
|
|
var offset: usize = 0
|
|
let wrote_line_text: Maybe<usize> = __zero_std_http_write(buffer, offset, start_line)
|
|
if !wrote_line_text.has {
|
|
return null
|
|
}
|
|
offset = wrote_line_text.value
|
|
let wrote_line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\ncontent-type: application/json\r\n")
|
|
if !wrote_line.has {
|
|
return null
|
|
}
|
|
offset = wrote_line.value
|
|
let headers_written: Maybe<usize> = __zero_std_http_write_header_block(buffer, offset, headers)
|
|
if !headers_written.has {
|
|
return null
|
|
}
|
|
offset = headers_written.value
|
|
let wrote_length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, std.mem.len(body))
|
|
if !wrote_length.has {
|
|
return null
|
|
}
|
|
offset = wrote_length.value
|
|
let wrote_blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !wrote_blank.has {
|
|
return null
|
|
}
|
|
offset = wrote_blank.value
|
|
let wrote_body: Maybe<usize> = __zero_std_http_write(buffer, offset, body)
|
|
if !wrote_body.has {
|
|
return null
|
|
}
|
|
return buffer[..wrote_body.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_text_ok(buffer: MutSpan<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return std.http.writeTextResponse(buffer, 200_u16, body)
|
|
}
|
|
|
|
fn __zero_std_http_write_html_ok(buffer: MutSpan<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return std.http.writeHtmlResponse(buffer, 200_u16, body)
|
|
}
|
|
|
|
fn __zero_std_http_path_ends_ignore_ascii_case(path: Span<u8>, suffix: Span<u8>) -> Bool {
|
|
let path_len: usize = std.mem.len(path)
|
|
let suffix_len: usize = std.mem.len(suffix)
|
|
if suffix_len > path_len {
|
|
return false
|
|
}
|
|
return std.str.eqlIgnoreAsciiCase(path[path_len - suffix_len..], suffix)
|
|
}
|
|
|
|
fn __zero_std_http_content_type_for_path(path: Span<u8>) -> String {
|
|
if __zero_std_http_path_ends_ignore_ascii_case(path, ".html") || __zero_std_http_path_ends_ignore_ascii_case(path, ".htm") {
|
|
return "text/html; charset=utf-8"
|
|
}
|
|
if __zero_std_http_path_ends_ignore_ascii_case(path, ".css") {
|
|
return "text/css; charset=utf-8"
|
|
}
|
|
if __zero_std_http_path_ends_ignore_ascii_case(path, ".js") || __zero_std_http_path_ends_ignore_ascii_case(path, ".mjs") {
|
|
return "text/javascript; charset=utf-8"
|
|
}
|
|
if __zero_std_http_path_ends_ignore_ascii_case(path, ".json") {
|
|
return "application/json"
|
|
}
|
|
if __zero_std_http_path_ends_ignore_ascii_case(path, ".txt") {
|
|
return "text/plain; charset=utf-8"
|
|
}
|
|
if __zero_std_http_path_ends_ignore_ascii_case(path, ".svg") {
|
|
return "image/svg+xml"
|
|
}
|
|
if __zero_std_http_path_ends_ignore_ascii_case(path, ".png") {
|
|
return "image/png"
|
|
}
|
|
if __zero_std_http_path_ends_ignore_ascii_case(path, ".jpg") || __zero_std_http_path_ends_ignore_ascii_case(path, ".jpeg") {
|
|
return "image/jpeg"
|
|
}
|
|
if __zero_std_http_path_ends_ignore_ascii_case(path, ".gif") {
|
|
return "image/gif"
|
|
}
|
|
if __zero_std_http_path_ends_ignore_ascii_case(path, ".webp") {
|
|
return "image/webp"
|
|
}
|
|
if __zero_std_http_path_ends_ignore_ascii_case(path, ".wasm") {
|
|
return "application/wasm"
|
|
}
|
|
if __zero_std_http_path_ends_ignore_ascii_case(path, ".xml") {
|
|
return "application/xml"
|
|
}
|
|
if __zero_std_http_path_ends_ignore_ascii_case(path, ".csv") {
|
|
return "text/csv; charset=utf-8"
|
|
}
|
|
return "application/octet-stream"
|
|
}
|
|
|
|
fn __zero_std_http_write_static_response(buffer: MutSpan<u8>, status: u16, path: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
let content_type: String = __zero_std_http_content_type_for_path(path)
|
|
return __zero_std_http_write_typed_response(buffer, status, std.mem.span(content_type), body)
|
|
}
|
|
|
|
fn __zero_std_http_test_request(buffer: MutSpan<u8>, method: Span<u8>, target: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_http_write_method_request(buffer, method, target, body)
|
|
}
|
|
|
|
fn __zero_std_http_test_json_request(buffer: MutSpan<u8>, method: Span<u8>, target: Span<u8>, body: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_http_write_json_method_request(buffer, method, target, body)
|
|
}
|
|
|
|
fn __zero_std_http_header_value_safe(value: Span<u8>) -> Bool {
|
|
if std.mem.len(value) == 0 {
|
|
return false
|
|
}
|
|
var index: usize = 0
|
|
while index < std.mem.len(value) {
|
|
let byte: u8 = value[index]
|
|
if byte < 32_u8 || byte == 127_u8 {
|
|
return false
|
|
}
|
|
index = index + 1
|
|
}
|
|
return true
|
|
}
|
|
|
|
fn __zero_std_http_write_redirect(buffer: MutSpan<u8>, status: u16, location: Span<u8>) -> Maybe<Span<u8>> {
|
|
let redirect_status: Bool = __zero_std_http_status_is_redirect(status)
|
|
if !redirect_status {
|
|
return null
|
|
}
|
|
let safe_location: Bool = __zero_std_http_header_value_safe(location)
|
|
if !safe_location {
|
|
return null
|
|
}
|
|
var offset: usize = 0
|
|
let prefix: Maybe<usize> = __zero_std_http_write(buffer, offset, "HTTP/1.1 ")
|
|
if !prefix.has {
|
|
return null
|
|
}
|
|
offset = prefix.value
|
|
let status_value: usize = status as usize
|
|
let code: Maybe<usize> = __zero_std_http_write_usize(buffer, offset, status_value)
|
|
if !code.has {
|
|
return null
|
|
}
|
|
offset = code.value
|
|
let space: Maybe<usize> = __zero_std_http_write(buffer, offset, " ")
|
|
if !space.has {
|
|
return null
|
|
}
|
|
offset = space.value
|
|
let reason_text: String = __zero_std_http_status_reason(status)
|
|
let reason_span: Span<u8> = std.mem.span(reason_text)
|
|
let reason: Maybe<usize> = __zero_std_http_write(buffer, offset, reason_span)
|
|
if !reason.has {
|
|
return null
|
|
}
|
|
offset = reason.value
|
|
let location_label: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\nlocation: ")
|
|
if !location_label.has {
|
|
return null
|
|
}
|
|
offset = location_label.value
|
|
let location_value: Maybe<usize> = __zero_std_http_write(buffer, offset, location)
|
|
if !location_value.has {
|
|
return null
|
|
}
|
|
offset = location_value.value
|
|
let line: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\nconnection: close\r\n")
|
|
if !line.has {
|
|
return null
|
|
}
|
|
offset = line.value
|
|
let body_len: usize = 0
|
|
let length: Maybe<usize> = __zero_std_http_write_content_length(buffer, offset, body_len)
|
|
if !length.has {
|
|
return null
|
|
}
|
|
offset = length.value
|
|
let blank: Maybe<usize> = __zero_std_http_write(buffer, offset, "\r\n")
|
|
if !blank.has {
|
|
return null
|
|
}
|
|
return buffer[..blank.value]
|
|
}
|
|
|
|
fn __zero_std_http_write_found(buffer: MutSpan<u8>, location: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_http_write_redirect(buffer, 302_u16, location)
|
|
}
|
|
|
|
fn __zero_std_http_write_see_other(buffer: MutSpan<u8>, location: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_http_write_redirect(buffer, 303_u16, location)
|
|
}
|
|
|
|
fn __zero_std_http_write_moved_permanently(buffer: MutSpan<u8>, location: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_http_write_redirect(buffer, 301_u16, location)
|
|
}
|
|
|
|
fn __zero_std_http_write_permanent_redirect(buffer: MutSpan<u8>, location: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_http_write_redirect(buffer, 308_u16, location)
|
|
}
|
|
|
|
fn __zero_std_io_write_byte(buffer: MutSpan<u8>, offset: usize, byte: u8) -> Maybe<usize> {
|
|
if offset >= std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[offset] = byte
|
|
return offset + 1
|
|
}
|
|
|
|
fn __zero_std_io_write_span(buffer: MutSpan<u8>, offset: usize, bytes: Span<u8>) -> Maybe<usize> {
|
|
if offset > std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
if std.mem.len(bytes) > std.mem.len(buffer) - offset {
|
|
return null
|
|
}
|
|
var index: usize = 0
|
|
while index < std.mem.len(bytes) {
|
|
buffer[offset + index] = bytes[index]
|
|
index = index + 1
|
|
}
|
|
return offset + std.mem.len(bytes)
|
|
}
|
|
|
|
fn __zero_std_io_written(buffer: Span<u8>, len: usize) -> Span<u8> {
|
|
if len > std.mem.len(buffer) {
|
|
return buffer
|
|
}
|
|
return buffer[..len]
|
|
}
|
|
|
|
fn __zero_std_io_remaining(buffer: Span<u8>, offset: usize) -> usize {
|
|
if offset >= std.mem.len(buffer) {
|
|
return 0
|
|
}
|
|
return std.mem.len(buffer) - offset
|
|
}
|
|
|
|
fn __zero_std_io_next_line(bytes: Span<u8>, start: usize) -> Maybe<Span<u8>> {
|
|
if start >= std.mem.len(bytes) {
|
|
return null
|
|
}
|
|
var end: usize = start
|
|
while end < std.mem.len(bytes) && bytes[end] != 10_u8 {
|
|
end = end + 1
|
|
}
|
|
if end > start && bytes[end - 1] == 13_u8 {
|
|
return bytes[start..end - 1]
|
|
}
|
|
return bytes[start..end]
|
|
}
|
|
|
|
fn __zero_std_io_next_line_start(bytes: Span<u8>, start: usize) -> usize {
|
|
if start >= std.mem.len(bytes) {
|
|
return std.mem.len(bytes)
|
|
}
|
|
var end: usize = start
|
|
while end < std.mem.len(bytes) && bytes[end] != 10_u8 {
|
|
end = end + 1
|
|
}
|
|
if end < std.mem.len(bytes) {
|
|
return end + 1
|
|
}
|
|
return std.mem.len(bytes)
|
|
}
|
|
|
|
fn __zero_std_io_count_lines(bytes: Span<u8>) -> usize {
|
|
var start: usize = 0
|
|
var count: usize = 0
|
|
while start < std.mem.len(bytes) {
|
|
count = count + 1
|
|
start = __zero_std_io_next_line_start(bytes, start)
|
|
}
|
|
return count
|
|
}
|
|
|
|
fn __zero_std_json_decode_boundary() -> String {
|
|
return "typed-decode-explicit-shape"
|
|
}
|
|
|
|
fn __zero_std_json_write_string(buffer: MutSpan<u8>, text: Span<u8>) -> Maybe<Span<u8>> {
|
|
return __zero_std_json_write_string_bytes(buffer, text)
|
|
}
|
|
|
|
fn __zero_std_json_validate(bytes: Span<u8>) -> Bool {
|
|
return __zero_std_json_validate_error(bytes) == __zero_std_json_error_none()
|
|
}
|
|
|
|
fn __zero_std_json_validate_bytes(bytes: Span<u8>) -> Bool {
|
|
return __zero_std_json_validate(bytes)
|
|
}
|
|
|
|
fn __zero_std_json_stream_tokens(bytes: Span<u8>) -> usize {
|
|
let count: Maybe<usize> = __zero_std_json_token_count(bytes)
|
|
if count.has {
|
|
return count.value
|
|
}
|
|
return 0_usize
|
|
}
|
|
|
|
fn __zero_std_json_stream_tokens_bytes(bytes: Span<u8>) -> usize {
|
|
return __zero_std_json_stream_tokens(bytes)
|
|
}
|
|
|
|
fn __zero_std_json_error_none() -> u32 {
|
|
return 0_u32
|
|
}
|
|
|
|
fn __zero_std_json_error_invalid() -> u32 {
|
|
return 1_u32
|
|
}
|
|
|
|
fn __zero_std_json_error_trailing() -> u32 {
|
|
return 2_u32
|
|
}
|
|
|
|
fn __zero_std_json_is_ws(byte: u8) -> Bool {
|
|
return byte == 32_u8 || byte == 9_u8 || byte == 10_u8 || byte == 13_u8
|
|
}
|
|
|
|
fn __zero_std_json_skip_ws(bytes: Span<u8>, start: usize) -> usize {
|
|
var index: usize = start
|
|
while index < std.mem.len(bytes) && __zero_std_json_is_ws(bytes[index]) {
|
|
index = index + 1
|
|
}
|
|
return index
|
|
}
|
|
|
|
fn __zero_std_json_is_digit(byte: u8) -> Bool {
|
|
return byte >= 48_u8 && byte <= 57_u8
|
|
}
|
|
|
|
fn __zero_std_json_literal_end(bytes: Span<u8>, start: usize, literal: Span<u8>) -> Maybe<usize> {
|
|
if std.mem.len(bytes) - start < std.mem.len(literal) {
|
|
return null
|
|
}
|
|
var index: usize = 0
|
|
while index < std.mem.len(literal) {
|
|
if bytes[start + index] != literal[index] {
|
|
return null
|
|
}
|
|
index = index + 1
|
|
}
|
|
return start + std.mem.len(literal)
|
|
}
|
|
|
|
fn __zero_std_json_hex_u16(bytes: Span<u8>, start: usize) -> Maybe<u16> {
|
|
if start + 3 >= std.mem.len(bytes) {
|
|
return null
|
|
}
|
|
let h0: Maybe<u8> = std.ascii.hexValue(bytes[start])
|
|
let h1: Maybe<u8> = std.ascii.hexValue(bytes[start + 1])
|
|
let h2: Maybe<u8> = std.ascii.hexValue(bytes[start + 2])
|
|
let h3: Maybe<u8> = std.ascii.hexValue(bytes[start + 3])
|
|
if !h0.has || !h1.has || !h2.has || !h3.has {
|
|
return null
|
|
}
|
|
return h0.value as u16 * 4096_u16 + h1.value as u16 * 256_u16 + h2.value as u16 * 16_u16 + h3.value as u16
|
|
}
|
|
|
|
fn __zero_std_json_is_high_surrogate(value: u16) -> Bool {
|
|
return value >= 0xd800_u16 && value <= 0xdbff_u16
|
|
}
|
|
|
|
fn __zero_std_json_is_low_surrogate(value: u16) -> Bool {
|
|
return value >= 0xdc00_u16 && value <= 0xdfff_u16
|
|
}
|
|
|
|
fn __zero_std_json_surrogate_codepoint(high: u16, low: u16) -> u32 {
|
|
return 65536_u32 + (high as u32 - 55296_u32) * 1024_u32 + (low as u32 - 56320_u32)
|
|
}
|
|
|
|
fn __zero_std_json_utf8_sequence_len(first: u8) -> usize {
|
|
if first < 128_u8 {
|
|
return 1
|
|
}
|
|
if first >= 194_u8 && first <= 223_u8 {
|
|
return 2
|
|
}
|
|
if first >= 224_u8 && first <= 239_u8 {
|
|
return 3
|
|
}
|
|
if first >= 240_u8 && first <= 244_u8 {
|
|
return 4
|
|
}
|
|
return 0
|
|
}
|
|
|
|
fn __zero_std_json_is_utf8_cont(byte: u8) -> Bool {
|
|
return byte >= 128_u8 && byte <= 191_u8
|
|
}
|
|
|
|
fn __zero_std_json_raw_utf8_width(bytes: Span<u8>, start: usize, end: usize) -> Maybe<usize> {
|
|
if start >= end {
|
|
return null
|
|
}
|
|
let first: u8 = bytes[start]
|
|
let width: usize = __zero_std_json_utf8_sequence_len(first)
|
|
if width == 0 || start + width > end {
|
|
return null
|
|
}
|
|
if width == 1 {
|
|
return 1_usize
|
|
}
|
|
let second: u8 = bytes[start + 1]
|
|
if width == 2 {
|
|
if !__zero_std_json_is_utf8_cont(second) {
|
|
return null
|
|
}
|
|
return 2_usize
|
|
}
|
|
if width == 3 {
|
|
if !__zero_std_json_is_utf8_cont(second) || !__zero_std_json_is_utf8_cont(bytes[start + 2]) {
|
|
return null
|
|
}
|
|
if first == 224_u8 && second < 160_u8 {
|
|
return null
|
|
}
|
|
if first == 237_u8 && second > 159_u8 {
|
|
return null
|
|
}
|
|
return 3_usize
|
|
}
|
|
if !__zero_std_json_is_utf8_cont(second) || !__zero_std_json_is_utf8_cont(bytes[start + 2]) || !__zero_std_json_is_utf8_cont(bytes[start + 3]) {
|
|
return null
|
|
}
|
|
if first == 240_u8 && second < 144_u8 {
|
|
return null
|
|
}
|
|
if first == 244_u8 && second > 143_u8 {
|
|
return null
|
|
}
|
|
return 4_usize
|
|
}
|
|
|
|
fn __zero_std_json_write_utf8(buffer: MutSpan<u8>, output: usize, codepoint: u32) -> Maybe<usize> {
|
|
if codepoint <= 127_u32 {
|
|
if output >= std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[output] = codepoint as u8
|
|
return output + 1
|
|
}
|
|
if codepoint <= 2047_u32 {
|
|
if output + 2 > std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[output] = 192_u8 + (codepoint / 64_u32) as u8
|
|
buffer[output + 1] = 128_u8 + (codepoint % 64_u32) as u8
|
|
return output + 2
|
|
}
|
|
if codepoint <= 65535_u32 {
|
|
if codepoint >= 55296_u32 && codepoint <= 57343_u32 {
|
|
return null
|
|
}
|
|
if output + 3 > std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[output] = 224_u8 + (codepoint / 4096_u32) as u8
|
|
buffer[output + 1] = 128_u8 + (codepoint / 64_u32 % 64_u32) as u8
|
|
buffer[output + 2] = 128_u8 + (codepoint % 64_u32) as u8
|
|
return output + 3
|
|
}
|
|
if codepoint <= 1114111_u32 {
|
|
if output + 4 > std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[output] = 240_u8 + (codepoint / 262144_u32) as u8
|
|
buffer[output + 1] = 128_u8 + (codepoint / 4096_u32 % 64_u32) as u8
|
|
buffer[output + 2] = 128_u8 + (codepoint / 64_u32 % 64_u32) as u8
|
|
buffer[output + 3] = 128_u8 + (codepoint % 64_u32) as u8
|
|
return output + 4
|
|
}
|
|
return null
|
|
}
|
|
|
|
fn __zero_std_json_string_end(bytes: Span<u8>, start: usize) -> Maybe<usize> {
|
|
if start >= std.mem.len(bytes) || bytes[start] != 34_u8 {
|
|
return null
|
|
}
|
|
var index: usize = start + 1
|
|
while index < std.mem.len(bytes) {
|
|
let byte: u8 = bytes[index]
|
|
if byte == 34_u8 {
|
|
return index + 1
|
|
}
|
|
if byte < 32_u8 {
|
|
return null
|
|
}
|
|
if byte == 92_u8 {
|
|
index = index + 1
|
|
if index >= std.mem.len(bytes) {
|
|
return null
|
|
}
|
|
let escaped: u8 = bytes[index]
|
|
if escaped == 117_u8 {
|
|
let unit: Maybe<u16> = __zero_std_json_hex_u16(bytes, index + 1)
|
|
if !unit.has {
|
|
return null
|
|
}
|
|
if __zero_std_json_is_high_surrogate(unit.value) {
|
|
if index + 10 >= std.mem.len(bytes) || bytes[index + 5] != 92_u8 || bytes[index + 6] != 117_u8 {
|
|
return null
|
|
}
|
|
let low: Maybe<u16> = __zero_std_json_hex_u16(bytes, index + 7)
|
|
if !low.has || !__zero_std_json_is_low_surrogate(low.value) {
|
|
return null
|
|
}
|
|
index = index + 11
|
|
} else if __zero_std_json_is_low_surrogate(unit.value) {
|
|
return null
|
|
} else {
|
|
index = index + 5
|
|
}
|
|
} else if escaped == 34_u8 || escaped == 92_u8 || escaped == 47_u8 || escaped == 98_u8 || escaped == 102_u8 || escaped == 110_u8 || escaped == 114_u8 || escaped == 116_u8 {
|
|
index = index + 1
|
|
} else {
|
|
return null
|
|
}
|
|
} else if byte >= 128_u8 {
|
|
let width: Maybe<usize> = __zero_std_json_raw_utf8_width(bytes, index, std.mem.len(bytes))
|
|
if !width.has {
|
|
return null
|
|
}
|
|
index = index + width.value
|
|
} else {
|
|
index = index + 1
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
fn __zero_std_json_number_end(bytes: Span<u8>, start: usize) -> Maybe<usize> {
|
|
var index: usize = start
|
|
if index < std.mem.len(bytes) && bytes[index] == 45_u8 {
|
|
index = index + 1
|
|
}
|
|
if index >= std.mem.len(bytes) {
|
|
return null
|
|
}
|
|
if bytes[index] == 48_u8 {
|
|
index = index + 1
|
|
} else if bytes[index] >= 49_u8 && bytes[index] <= 57_u8 {
|
|
while index < std.mem.len(bytes) && __zero_std_json_is_digit(bytes[index]) {
|
|
index = index + 1
|
|
}
|
|
} else {
|
|
return null
|
|
}
|
|
if index < std.mem.len(bytes) && bytes[index] == 46_u8 {
|
|
index = index + 1
|
|
let first_fraction: usize = index
|
|
while index < std.mem.len(bytes) && __zero_std_json_is_digit(bytes[index]) {
|
|
index = index + 1
|
|
}
|
|
if first_fraction == index {
|
|
return null
|
|
}
|
|
}
|
|
if index < std.mem.len(bytes) && (bytes[index] == 101_u8 || bytes[index] == 69_u8) {
|
|
index = index + 1
|
|
if index < std.mem.len(bytes) && (bytes[index] == 43_u8 || bytes[index] == 45_u8) {
|
|
index = index + 1
|
|
}
|
|
let first_exp: usize = index
|
|
while index < std.mem.len(bytes) && __zero_std_json_is_digit(bytes[index]) {
|
|
index = index + 1
|
|
}
|
|
if first_exp == index {
|
|
return null
|
|
}
|
|
}
|
|
return index
|
|
}
|
|
|
|
fn __zero_std_json_value_end(bytes: Span<u8>, start: usize) -> Maybe<usize> {
|
|
var index: usize = __zero_std_json_skip_ws(bytes, start)
|
|
if index >= std.mem.len(bytes) {
|
|
return null
|
|
}
|
|
var states: [64]u8 = [0_u8; 64]
|
|
var depth: usize = 0
|
|
while index < std.mem.len(bytes) {
|
|
if depth == 0 {
|
|
let byte: u8 = bytes[index]
|
|
if byte == 123_u8 {
|
|
states[depth] = 2_u8
|
|
depth = depth + 1
|
|
index = index + 1
|
|
} else if byte == 91_u8 {
|
|
states[depth] = 0_u8
|
|
depth = depth + 1
|
|
index = index + 1
|
|
} else if byte == 34_u8 {
|
|
return __zero_std_json_string_end(bytes, index)
|
|
} else if byte == 116_u8 {
|
|
return __zero_std_json_literal_end(bytes, index, "true")
|
|
} else if byte == 102_u8 {
|
|
return __zero_std_json_literal_end(bytes, index, "false")
|
|
} else if byte == 110_u8 {
|
|
return __zero_std_json_literal_end(bytes, index, "null")
|
|
} else {
|
|
return __zero_std_json_number_end(bytes, index)
|
|
}
|
|
} else {
|
|
index = __zero_std_json_skip_ws(bytes, index)
|
|
if index >= std.mem.len(bytes) {
|
|
return null
|
|
}
|
|
let state: u8 = states[depth - 1]
|
|
if state == 0_u8 {
|
|
let byte: u8 = bytes[index]
|
|
if byte == 93_u8 {
|
|
depth = depth - 1
|
|
index = index + 1
|
|
if depth == 0 {
|
|
return index
|
|
}
|
|
} else if byte == 123_u8 {
|
|
states[depth - 1] = 1_u8
|
|
if depth >= 64 {
|
|
return null
|
|
}
|
|
states[depth] = 2_u8
|
|
depth = depth + 1
|
|
index = index + 1
|
|
} else if byte == 91_u8 {
|
|
states[depth - 1] = 1_u8
|
|
if depth >= 64 {
|
|
return null
|
|
}
|
|
states[depth] = 0_u8
|
|
depth = depth + 1
|
|
index = index + 1
|
|
} else if byte == 34_u8 {
|
|
let end: Maybe<usize> = __zero_std_json_string_end(bytes, index)
|
|
if !end.has {
|
|
return null
|
|
}
|
|
index = end.value
|
|
states[depth - 1] = 1_u8
|
|
} else if byte == 116_u8 {
|
|
let end: Maybe<usize> = __zero_std_json_literal_end(bytes, index, "true")
|
|
if !end.has {
|
|
return null
|
|
}
|
|
index = end.value
|
|
states[depth - 1] = 1_u8
|
|
} else if byte == 102_u8 {
|
|
let end: Maybe<usize> = __zero_std_json_literal_end(bytes, index, "false")
|
|
if !end.has {
|
|
return null
|
|
}
|
|
index = end.value
|
|
states[depth - 1] = 1_u8
|
|
} else if byte == 110_u8 {
|
|
let end: Maybe<usize> = __zero_std_json_literal_end(bytes, index, "null")
|
|
if !end.has {
|
|
return null
|
|
}
|
|
index = end.value
|
|
states[depth - 1] = 1_u8
|
|
} else {
|
|
let end: Maybe<usize> = __zero_std_json_number_end(bytes, index)
|
|
if !end.has {
|
|
return null
|
|
}
|
|
index = end.value
|
|
states[depth - 1] = 1_u8
|
|
}
|
|
} else if state == 1_u8 {
|
|
if bytes[index] == 44_u8 {
|
|
index = index + 1
|
|
let next: usize = __zero_std_json_skip_ws(bytes, index)
|
|
if next >= std.mem.len(bytes) || bytes[next] == 93_u8 {
|
|
return null
|
|
}
|
|
states[depth - 1] = 0_u8
|
|
} else if bytes[index] == 93_u8 {
|
|
depth = depth - 1
|
|
index = index + 1
|
|
if depth == 0 {
|
|
return index
|
|
}
|
|
} else {
|
|
return null
|
|
}
|
|
} else if state == 2_u8 {
|
|
if bytes[index] == 125_u8 {
|
|
depth = depth - 1
|
|
index = index + 1
|
|
if depth == 0 {
|
|
return index
|
|
}
|
|
} else {
|
|
let end: Maybe<usize> = __zero_std_json_string_end(bytes, index)
|
|
if !end.has {
|
|
return null
|
|
}
|
|
index = end.value
|
|
states[depth - 1] = 3_u8
|
|
}
|
|
} else if state == 3_u8 {
|
|
if bytes[index] != 58_u8 {
|
|
return null
|
|
}
|
|
states[depth - 1] = 4_u8
|
|
index = index + 1
|
|
} else if state == 4_u8 {
|
|
let byte: u8 = bytes[index]
|
|
if byte == 123_u8 {
|
|
states[depth - 1] = 5_u8
|
|
if depth >= 64 {
|
|
return null
|
|
}
|
|
states[depth] = 2_u8
|
|
depth = depth + 1
|
|
index = index + 1
|
|
} else if byte == 91_u8 {
|
|
states[depth - 1] = 5_u8
|
|
if depth >= 64 {
|
|
return null
|
|
}
|
|
states[depth] = 0_u8
|
|
depth = depth + 1
|
|
index = index + 1
|
|
} else if byte == 34_u8 {
|
|
let end: Maybe<usize> = __zero_std_json_string_end(bytes, index)
|
|
if !end.has {
|
|
return null
|
|
}
|
|
index = end.value
|
|
states[depth - 1] = 5_u8
|
|
} else if byte == 116_u8 {
|
|
let end: Maybe<usize> = __zero_std_json_literal_end(bytes, index, "true")
|
|
if !end.has {
|
|
return null
|
|
}
|
|
index = end.value
|
|
states[depth - 1] = 5_u8
|
|
} else if byte == 102_u8 {
|
|
let end: Maybe<usize> = __zero_std_json_literal_end(bytes, index, "false")
|
|
if !end.has {
|
|
return null
|
|
}
|
|
index = end.value
|
|
states[depth - 1] = 5_u8
|
|
} else if byte == 110_u8 {
|
|
let end: Maybe<usize> = __zero_std_json_literal_end(bytes, index, "null")
|
|
if !end.has {
|
|
return null
|
|
}
|
|
index = end.value
|
|
states[depth - 1] = 5_u8
|
|
} else {
|
|
let end: Maybe<usize> = __zero_std_json_number_end(bytes, index)
|
|
if !end.has {
|
|
return null
|
|
}
|
|
index = end.value
|
|
states[depth - 1] = 5_u8
|
|
}
|
|
} else if state == 5_u8 {
|
|
if bytes[index] == 44_u8 {
|
|
index = index + 1
|
|
let next: usize = __zero_std_json_skip_ws(bytes, index)
|
|
if next >= std.mem.len(bytes) || bytes[next] == 125_u8 {
|
|
return null
|
|
}
|
|
states[depth - 1] = 2_u8
|
|
} else if bytes[index] == 125_u8 {
|
|
depth = depth - 1
|
|
index = index + 1
|
|
if depth == 0 {
|
|
return index
|
|
}
|
|
} else {
|
|
return null
|
|
}
|
|
} else {
|
|
return null
|
|
}
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
fn __zero_std_json_token_count(bytes: Span<u8>) -> Maybe<usize> {
|
|
var index: usize = __zero_std_json_skip_ws(bytes, 0)
|
|
if index >= std.mem.len(bytes) {
|
|
return null
|
|
}
|
|
var states: [64]u8 = [0_u8; 64]
|
|
var depth: usize = 0
|
|
var tokens: usize = 0
|
|
while index < std.mem.len(bytes) {
|
|
if depth == 0 {
|
|
let byte: u8 = bytes[index]
|
|
if byte == 123_u8 {
|
|
tokens = tokens + 1
|
|
states[depth] = 2_u8
|
|
depth = depth + 1
|
|
index = index + 1
|
|
} else if byte == 91_u8 {
|
|
tokens = tokens + 1
|
|
states[depth] = 0_u8
|
|
depth = depth + 1
|
|
index = index + 1
|
|
} else {
|
|
var end: Maybe<usize> = null
|
|
if byte == 34_u8 {
|
|
end = __zero_std_json_string_end(bytes, index)
|
|
} else if byte == 116_u8 {
|
|
end = __zero_std_json_literal_end(bytes, index, "true")
|
|
} else if byte == 102_u8 {
|
|
end = __zero_std_json_literal_end(bytes, index, "false")
|
|
} else if byte == 110_u8 {
|
|
end = __zero_std_json_literal_end(bytes, index, "null")
|
|
} else {
|
|
end = __zero_std_json_number_end(bytes, index)
|
|
}
|
|
if !end.has {
|
|
return null
|
|
}
|
|
let trailing: usize = __zero_std_json_skip_ws(bytes, end.value)
|
|
if trailing == std.mem.len(bytes) {
|
|
return tokens + 1
|
|
}
|
|
return null
|
|
}
|
|
} else {
|
|
index = __zero_std_json_skip_ws(bytes, index)
|
|
if index >= std.mem.len(bytes) {
|
|
return null
|
|
}
|
|
let state: u8 = states[depth - 1]
|
|
if state == 0_u8 {
|
|
let byte: u8 = bytes[index]
|
|
if byte == 93_u8 {
|
|
depth = depth - 1
|
|
index = index + 1
|
|
if depth == 0 {
|
|
let trailing: usize = __zero_std_json_skip_ws(bytes, index)
|
|
if trailing == std.mem.len(bytes) {
|
|
return tokens
|
|
}
|
|
return null
|
|
}
|
|
} else if byte == 123_u8 {
|
|
tokens = tokens + 1
|
|
states[depth - 1] = 1_u8
|
|
if depth >= 64 {
|
|
return null
|
|
}
|
|
states[depth] = 2_u8
|
|
depth = depth + 1
|
|
index = index + 1
|
|
} else if byte == 91_u8 {
|
|
tokens = tokens + 1
|
|
states[depth - 1] = 1_u8
|
|
if depth >= 64 {
|
|
return null
|
|
}
|
|
states[depth] = 0_u8
|
|
depth = depth + 1
|
|
index = index + 1
|
|
} else {
|
|
var end: Maybe<usize> = null
|
|
if byte == 34_u8 {
|
|
end = __zero_std_json_string_end(bytes, index)
|
|
} else if byte == 116_u8 {
|
|
end = __zero_std_json_literal_end(bytes, index, "true")
|
|
} else if byte == 102_u8 {
|
|
end = __zero_std_json_literal_end(bytes, index, "false")
|
|
} else if byte == 110_u8 {
|
|
end = __zero_std_json_literal_end(bytes, index, "null")
|
|
} else {
|
|
end = __zero_std_json_number_end(bytes, index)
|
|
}
|
|
if !end.has {
|
|
return null
|
|
}
|
|
tokens = tokens + 1
|
|
index = end.value
|
|
states[depth - 1] = 1_u8
|
|
}
|
|
} else if state == 1_u8 {
|
|
if bytes[index] == 44_u8 {
|
|
index = index + 1
|
|
let next: usize = __zero_std_json_skip_ws(bytes, index)
|
|
if next >= std.mem.len(bytes) || bytes[next] == 93_u8 {
|
|
return null
|
|
}
|
|
states[depth - 1] = 0_u8
|
|
} else if bytes[index] == 93_u8 {
|
|
depth = depth - 1
|
|
index = index + 1
|
|
if depth == 0 {
|
|
let trailing: usize = __zero_std_json_skip_ws(bytes, index)
|
|
if trailing == std.mem.len(bytes) {
|
|
return tokens
|
|
}
|
|
return null
|
|
}
|
|
} else {
|
|
return null
|
|
}
|
|
} else if state == 2_u8 {
|
|
if bytes[index] == 125_u8 {
|
|
depth = depth - 1
|
|
index = index + 1
|
|
if depth == 0 {
|
|
let trailing: usize = __zero_std_json_skip_ws(bytes, index)
|
|
if trailing == std.mem.len(bytes) {
|
|
return tokens
|
|
}
|
|
return null
|
|
}
|
|
} else {
|
|
let end: Maybe<usize> = __zero_std_json_string_end(bytes, index)
|
|
if !end.has {
|
|
return null
|
|
}
|
|
tokens = tokens + 1
|
|
index = end.value
|
|
states[depth - 1] = 3_u8
|
|
}
|
|
} else if state == 3_u8 {
|
|
if bytes[index] != 58_u8 {
|
|
return null
|
|
}
|
|
states[depth - 1] = 4_u8
|
|
index = index + 1
|
|
} else if state == 4_u8 {
|
|
let byte: u8 = bytes[index]
|
|
if byte == 123_u8 {
|
|
tokens = tokens + 1
|
|
states[depth - 1] = 5_u8
|
|
if depth >= 64 {
|
|
return null
|
|
}
|
|
states[depth] = 2_u8
|
|
depth = depth + 1
|
|
index = index + 1
|
|
} else if byte == 91_u8 {
|
|
tokens = tokens + 1
|
|
states[depth - 1] = 5_u8
|
|
if depth >= 64 {
|
|
return null
|
|
}
|
|
states[depth] = 0_u8
|
|
depth = depth + 1
|
|
index = index + 1
|
|
} else {
|
|
var end: Maybe<usize> = null
|
|
if byte == 34_u8 {
|
|
end = __zero_std_json_string_end(bytes, index)
|
|
} else if byte == 116_u8 {
|
|
end = __zero_std_json_literal_end(bytes, index, "true")
|
|
} else if byte == 102_u8 {
|
|
end = __zero_std_json_literal_end(bytes, index, "false")
|
|
} else if byte == 110_u8 {
|
|
end = __zero_std_json_literal_end(bytes, index, "null")
|
|
} else {
|
|
end = __zero_std_json_number_end(bytes, index)
|
|
}
|
|
if !end.has {
|
|
return null
|
|
}
|
|
tokens = tokens + 1
|
|
index = end.value
|
|
states[depth - 1] = 5_u8
|
|
}
|
|
} else if state == 5_u8 {
|
|
if bytes[index] == 44_u8 {
|
|
index = index + 1
|
|
let next: usize = __zero_std_json_skip_ws(bytes, index)
|
|
if next >= std.mem.len(bytes) || bytes[next] == 125_u8 {
|
|
return null
|
|
}
|
|
states[depth - 1] = 2_u8
|
|
} else if bytes[index] == 125_u8 {
|
|
depth = depth - 1
|
|
index = index + 1
|
|
if depth == 0 {
|
|
let trailing: usize = __zero_std_json_skip_ws(bytes, index)
|
|
if trailing == std.mem.len(bytes) {
|
|
return tokens
|
|
}
|
|
return null
|
|
}
|
|
} else {
|
|
return null
|
|
}
|
|
} else {
|
|
return null
|
|
}
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
fn __zero_std_json_validate_error(bytes: Span<u8>) -> u32 {
|
|
let start: usize = __zero_std_json_skip_ws(bytes, 0)
|
|
let end: Maybe<usize> = __zero_std_json_value_end(bytes, start)
|
|
if !end.has {
|
|
return __zero_std_json_error_invalid()
|
|
}
|
|
let trailing: usize = __zero_std_json_skip_ws(bytes, end.value)
|
|
if trailing != std.mem.len(bytes) {
|
|
return __zero_std_json_error_trailing()
|
|
}
|
|
return __zero_std_json_error_none()
|
|
}
|
|
|
|
fn __zero_std_json_key_matches(bytes: Span<u8>, start: usize, end: usize, key: Span<u8>) -> Bool {
|
|
if start >= end || bytes[start] != 34_u8 {
|
|
return false
|
|
}
|
|
var input: usize = start + 1
|
|
var key_index: usize = 0
|
|
while input + 1 < end {
|
|
var decoded: u8 = bytes[input]
|
|
var unicode_matched: Bool = false
|
|
if decoded == 92_u8 {
|
|
input = input + 1
|
|
if input + 1 >= end {
|
|
return false
|
|
}
|
|
let escaped: u8 = bytes[input]
|
|
if escaped == 34_u8 {
|
|
decoded = 34_u8
|
|
} else if escaped == 92_u8 {
|
|
decoded = 92_u8
|
|
} else if escaped == 47_u8 {
|
|
decoded = 47_u8
|
|
} else if escaped == 98_u8 {
|
|
decoded = 8_u8
|
|
} else if escaped == 102_u8 {
|
|
decoded = 12_u8
|
|
} else if escaped == 110_u8 {
|
|
decoded = 10_u8
|
|
} else if escaped == 114_u8 {
|
|
decoded = 13_u8
|
|
} else if escaped == 116_u8 {
|
|
decoded = 9_u8
|
|
} else if escaped == 117_u8 {
|
|
let unit: Maybe<u16> = __zero_std_json_hex_u16(bytes, input + 1)
|
|
if !unit.has {
|
|
return false
|
|
}
|
|
var codepoint: u32 = unit.value as u32
|
|
if __zero_std_json_is_high_surrogate(unit.value) {
|
|
if input + 10 >= end || bytes[input + 5] != 92_u8 || bytes[input + 6] != 117_u8 {
|
|
return false
|
|
}
|
|
let low: Maybe<u16> = __zero_std_json_hex_u16(bytes, input + 7)
|
|
if !low.has || !__zero_std_json_is_low_surrogate(low.value) {
|
|
return false
|
|
}
|
|
codepoint = __zero_std_json_surrogate_codepoint(unit.value, low.value)
|
|
input = input + 10
|
|
} else if __zero_std_json_is_low_surrogate(unit.value) {
|
|
return false
|
|
} else {
|
|
input = input + 4
|
|
}
|
|
var scratch: [4]u8 = [0_u8; 4]
|
|
let written: Maybe<usize> = __zero_std_json_write_utf8(scratch, 0, codepoint)
|
|
if !written.has {
|
|
return false
|
|
}
|
|
var scratch_index: usize = 0
|
|
while scratch_index < written.value {
|
|
if key_index >= std.mem.len(key) || key[key_index] != scratch[scratch_index] {
|
|
return false
|
|
}
|
|
key_index = key_index + 1
|
|
scratch_index = scratch_index + 1
|
|
}
|
|
unicode_matched = true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
if !unicode_matched {
|
|
if key_index >= std.mem.len(key) || key[key_index] != decoded {
|
|
return false
|
|
}
|
|
key_index = key_index + 1
|
|
}
|
|
input = input + 1
|
|
}
|
|
return key_index == std.mem.len(key)
|
|
}
|
|
|
|
fn __zero_std_json_field(bytes: Span<u8>, key: Span<u8>) -> Maybe<Span<u8>> {
|
|
let start: usize = __zero_std_json_skip_ws(bytes, 0)
|
|
if start >= std.mem.len(bytes) || bytes[start] != 123_u8 {
|
|
return null
|
|
}
|
|
var index: usize = __zero_std_json_skip_ws(bytes, start + 1)
|
|
if index < std.mem.len(bytes) && bytes[index] == 125_u8 {
|
|
return null
|
|
}
|
|
var found: Bool = false
|
|
var found_start: usize = 0
|
|
var found_end: usize = 0
|
|
while index < std.mem.len(bytes) {
|
|
let key_end: Maybe<usize> = __zero_std_json_string_end(bytes, index)
|
|
if !key_end.has {
|
|
return null
|
|
}
|
|
let matched: Bool = __zero_std_json_key_matches(bytes, index, key_end.value, key)
|
|
index = __zero_std_json_skip_ws(bytes, key_end.value)
|
|
if index >= std.mem.len(bytes) || bytes[index] != 58_u8 {
|
|
return null
|
|
}
|
|
let value_start: usize = __zero_std_json_skip_ws(bytes, index + 1)
|
|
let value_end: Maybe<usize> = __zero_std_json_value_end(bytes, value_start)
|
|
if !value_end.has {
|
|
return null
|
|
}
|
|
if matched && !found {
|
|
found = true
|
|
found_start = value_start
|
|
found_end = value_end.value
|
|
}
|
|
index = __zero_std_json_skip_ws(bytes, value_end.value)
|
|
if index < std.mem.len(bytes) && bytes[index] == 125_u8 {
|
|
let trailing: usize = __zero_std_json_skip_ws(bytes, index + 1)
|
|
if trailing != std.mem.len(bytes) {
|
|
return null
|
|
}
|
|
if found {
|
|
return bytes[found_start..found_end]
|
|
}
|
|
return null
|
|
}
|
|
if index >= std.mem.len(bytes) || bytes[index] != 44_u8 {
|
|
return null
|
|
}
|
|
index = __zero_std_json_skip_ws(bytes, index + 1)
|
|
if index >= std.mem.len(bytes) || bytes[index] == 125_u8 {
|
|
return null
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
fn __zero_std_json_string_decode(buffer: MutSpan<u8>, value: Span<u8>) -> Maybe<Span<u8>> {
|
|
let end: Maybe<usize> = __zero_std_json_string_end(value, 0)
|
|
if !end.has || end.value != std.mem.len(value) {
|
|
return null
|
|
}
|
|
var input: usize = 1
|
|
var output: usize = 0
|
|
while input + 1 < std.mem.len(value) {
|
|
var decoded: u8 = value[input]
|
|
var unicode_written: Bool = false
|
|
if decoded == 92_u8 {
|
|
input = input + 1
|
|
let escaped: u8 = value[input]
|
|
if escaped == 34_u8 {
|
|
decoded = 34_u8
|
|
} else if escaped == 92_u8 {
|
|
decoded = 92_u8
|
|
} else if escaped == 47_u8 {
|
|
decoded = 47_u8
|
|
} else if escaped == 98_u8 {
|
|
decoded = 8_u8
|
|
} else if escaped == 102_u8 {
|
|
decoded = 12_u8
|
|
} else if escaped == 110_u8 {
|
|
decoded = 10_u8
|
|
} else if escaped == 114_u8 {
|
|
decoded = 13_u8
|
|
} else if escaped == 116_u8 {
|
|
decoded = 9_u8
|
|
} else if escaped == 117_u8 {
|
|
let unit: Maybe<u16> = __zero_std_json_hex_u16(value, input + 1)
|
|
if !unit.has {
|
|
return null
|
|
}
|
|
var codepoint: u32 = unit.value as u32
|
|
if __zero_std_json_is_high_surrogate(unit.value) {
|
|
if input + 10 >= std.mem.len(value) || value[input + 5] != 92_u8 || value[input + 6] != 117_u8 {
|
|
return null
|
|
}
|
|
let low: Maybe<u16> = __zero_std_json_hex_u16(value, input + 7)
|
|
if !low.has || !__zero_std_json_is_low_surrogate(low.value) {
|
|
return null
|
|
}
|
|
codepoint = __zero_std_json_surrogate_codepoint(unit.value, low.value)
|
|
input = input + 10
|
|
} else if __zero_std_json_is_low_surrogate(unit.value) {
|
|
return null
|
|
} else {
|
|
input = input + 4
|
|
}
|
|
let next: Maybe<usize> = __zero_std_json_write_utf8(buffer, output, codepoint)
|
|
if !next.has {
|
|
return null
|
|
}
|
|
output = next.value
|
|
unicode_written = true
|
|
} else {
|
|
return null
|
|
}
|
|
}
|
|
if !unicode_written {
|
|
if output >= std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[output] = decoded
|
|
output = output + 1
|
|
}
|
|
input = input + 1
|
|
}
|
|
return buffer[..output]
|
|
}
|
|
|
|
fn __zero_std_json_string(buffer: MutSpan<u8>, bytes: Span<u8>, key: Span<u8>) -> Maybe<Span<u8>> {
|
|
let raw: Maybe<Span<u8>> = __zero_std_json_field(bytes, key)
|
|
if !raw.has {
|
|
return null
|
|
}
|
|
return __zero_std_json_string_decode(buffer, raw.value)
|
|
}
|
|
|
|
fn __zero_std_json_u32(bytes: Span<u8>, key: Span<u8>) -> Maybe<u32> {
|
|
let raw: Maybe<Span<u8>> = __zero_std_json_field(bytes, key)
|
|
if !raw.has {
|
|
return null
|
|
}
|
|
return std.parse.parseU32(raw.value)
|
|
}
|
|
|
|
fn __zero_std_json_bool(bytes: Span<u8>, key: Span<u8>) -> Maybe<Bool> {
|
|
let raw: Maybe<Span<u8>> = __zero_std_json_field(bytes, key)
|
|
if !raw.has {
|
|
return null
|
|
}
|
|
return std.parse.parseBool(raw.value)
|
|
}
|
|
|
|
fn __zero_std_json_hex_char(value: u8) -> u8 {
|
|
if value < 10_u8 {
|
|
return 48_u8 + value
|
|
}
|
|
return 97_u8 + value - 10_u8
|
|
}
|
|
|
|
fn __zero_std_json_write_escape(buffer: MutSpan<u8>, output: usize, escaped: u8) -> Maybe<usize> {
|
|
if output + 2 > std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[output] = 92_u8
|
|
buffer[output + 1] = escaped
|
|
return output + 2
|
|
}
|
|
|
|
fn __zero_std_json_write_u_escape(buffer: MutSpan<u8>, output: usize, value: u8) -> Maybe<usize> {
|
|
if output + 6 > std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[output] = 92_u8
|
|
buffer[output + 1] = 117_u8
|
|
buffer[output + 2] = 48_u8
|
|
buffer[output + 3] = 48_u8
|
|
buffer[output + 4] = __zero_std_json_hex_char(value / 16_u8)
|
|
buffer[output + 5] = __zero_std_json_hex_char(value % 16_u8)
|
|
return output + 6
|
|
}
|
|
|
|
fn __zero_std_json_write_string_bytes(buffer: MutSpan<u8>, text: Span<u8>) -> Maybe<Span<u8>> {
|
|
if std.mem.len(buffer) < 2 {
|
|
return null
|
|
}
|
|
var output: usize = 0
|
|
buffer[output] = 34_u8
|
|
output = output + 1
|
|
var input: usize = 0
|
|
while input < std.mem.len(text) {
|
|
let byte: u8 = text[input]
|
|
var next_input: usize = input + 1
|
|
if byte == 34_u8 {
|
|
let next: Maybe<usize> = __zero_std_json_write_escape(buffer, output, 34_u8)
|
|
if !next.has {
|
|
return null
|
|
}
|
|
output = next.value
|
|
} else if byte == 92_u8 {
|
|
let next: Maybe<usize> = __zero_std_json_write_escape(buffer, output, 92_u8)
|
|
if !next.has {
|
|
return null
|
|
}
|
|
output = next.value
|
|
} else if byte == 8_u8 {
|
|
let next: Maybe<usize> = __zero_std_json_write_escape(buffer, output, 98_u8)
|
|
if !next.has {
|
|
return null
|
|
}
|
|
output = next.value
|
|
} else if byte == 12_u8 {
|
|
let next: Maybe<usize> = __zero_std_json_write_escape(buffer, output, 102_u8)
|
|
if !next.has {
|
|
return null
|
|
}
|
|
output = next.value
|
|
} else if byte == 10_u8 {
|
|
let next: Maybe<usize> = __zero_std_json_write_escape(buffer, output, 110_u8)
|
|
if !next.has {
|
|
return null
|
|
}
|
|
output = next.value
|
|
} else if byte == 13_u8 {
|
|
let next: Maybe<usize> = __zero_std_json_write_escape(buffer, output, 114_u8)
|
|
if !next.has {
|
|
return null
|
|
}
|
|
output = next.value
|
|
} else if byte == 9_u8 {
|
|
let next: Maybe<usize> = __zero_std_json_write_escape(buffer, output, 116_u8)
|
|
if !next.has {
|
|
return null
|
|
}
|
|
output = next.value
|
|
} else if byte < 32_u8 {
|
|
let next: Maybe<usize> = __zero_std_json_write_u_escape(buffer, output, byte)
|
|
if !next.has {
|
|
return null
|
|
}
|
|
output = next.value
|
|
} else if byte >= 128_u8 {
|
|
let width: Maybe<usize> = __zero_std_json_raw_utf8_width(text, input, std.mem.len(text))
|
|
if !width.has || output + width.value > std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
var utf8_index: usize = 0
|
|
while utf8_index < width.value {
|
|
buffer[output] = text[input + utf8_index]
|
|
output = output + 1
|
|
utf8_index = utf8_index + 1
|
|
}
|
|
next_input = input + width.value
|
|
} else {
|
|
if output >= std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[output] = byte
|
|
output = output + 1
|
|
}
|
|
input = next_input
|
|
}
|
|
if output >= std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[output] = 34_u8
|
|
return buffer[..output + 1]
|
|
}
|
|
|
|
fn __zero_std_json_write_object_key(buffer: MutSpan<u8>, key: Span<u8>) -> Maybe<usize> {
|
|
if std.mem.len(buffer) < 2 {
|
|
return null
|
|
}
|
|
buffer[0] = 123_u8
|
|
let written_key: Maybe<Span<u8>> = __zero_std_json_write_string_bytes(buffer[1..], key)
|
|
if !written_key.has {
|
|
return null
|
|
}
|
|
let cursor: usize = 1 + std.mem.len(written_key.value)
|
|
if cursor >= std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[cursor] = 58_u8
|
|
return cursor + 1
|
|
}
|
|
|
|
fn __zero_std_json_write_object_close(buffer: MutSpan<u8>, cursor: usize) -> Maybe<Span<u8>> {
|
|
if cursor >= std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[cursor] = 125_u8
|
|
return buffer[..cursor + 1]
|
|
}
|
|
|
|
fn __zero_std_json_write_object1_string(buffer: MutSpan<u8>, key: Span<u8>, value: Span<u8>) -> Maybe<Span<u8>> {
|
|
let cursor: Maybe<usize> = __zero_std_json_write_object_key(buffer, key)
|
|
if !cursor.has {
|
|
return null
|
|
}
|
|
let written_value: Maybe<Span<u8>> = __zero_std_json_write_string_bytes(buffer[cursor.value..], value)
|
|
if !written_value.has {
|
|
return null
|
|
}
|
|
return __zero_std_json_write_object_close(buffer, cursor.value + std.mem.len(written_value.value))
|
|
}
|
|
|
|
fn __zero_std_json_write_object1_u32(buffer: MutSpan<u8>, key: Span<u8>, value: u32) -> Maybe<Span<u8>> {
|
|
let cursor: Maybe<usize> = __zero_std_json_write_object_key(buffer, key)
|
|
if !cursor.has {
|
|
return null
|
|
}
|
|
let written_value: Maybe<Span<u8>> = std.fmt.u32(buffer[cursor.value..], value)
|
|
if !written_value.has {
|
|
return null
|
|
}
|
|
return __zero_std_json_write_object_close(buffer, cursor.value + std.mem.len(written_value.value))
|
|
}
|
|
|
|
fn __zero_std_json_write_object1_bool(buffer: MutSpan<u8>, key: Span<u8>, value: Bool) -> Maybe<Span<u8>> {
|
|
let cursor: Maybe<usize> = __zero_std_json_write_object_key(buffer, key)
|
|
if !cursor.has {
|
|
return null
|
|
}
|
|
let written_value: Maybe<Span<u8>> = std.fmt.bool(buffer[cursor.value..], value)
|
|
if !written_value.has {
|
|
return null
|
|
}
|
|
return __zero_std_json_write_object_close(buffer, cursor.value + std.mem.len(written_value.value))
|
|
}
|
|
|
|
fn __zero_std_mem_copy_items<T: Type>(dst: MutSpan<T>, src: Span<T>) -> usize {
|
|
var count: usize = std.mem.len(src)
|
|
let capacity: usize = std.mem.len(dst)
|
|
if count > capacity {
|
|
count = capacity
|
|
}
|
|
var index: usize = 0
|
|
while index < count {
|
|
dst[index] = src[index]
|
|
index = index + 1
|
|
}
|
|
return count
|
|
}
|
|
|
|
fn __zero_std_mem_fill_items<T: Type>(dst: MutSpan<T>, value: T) -> usize {
|
|
var index: usize = 0
|
|
let len: usize = std.mem.len(dst)
|
|
while index < len {
|
|
dst[index] = value
|
|
index = index + 1
|
|
}
|
|
return len
|
|
}
|
|
|
|
fn __zero_std_mem_contains<T: Type>(items: Span<T>, needle: T) -> Bool {
|
|
var index: usize = 0
|
|
while index < std.mem.len(items) {
|
|
if items[index] == needle {
|
|
return true
|
|
}
|
|
index = index + 1
|
|
}
|
|
return false
|
|
}
|
|
|
|
fn __zero_std_mem_is_empty<T: Type>(items: Span<T>) -> Bool {
|
|
return std.mem.len(items) == 0
|
|
}
|
|
|
|
fn __zero_std_mem_prefix<T: Type>(items: Span<T>, count: usize) -> Span<T> {
|
|
var end: usize = count
|
|
if end > std.mem.len(items) {
|
|
end = std.mem.len(items)
|
|
}
|
|
return items[..end]
|
|
}
|
|
|
|
fn __zero_std_mem_drop_prefix<T: Type>(items: Span<T>, count: usize) -> Span<T> {
|
|
var start: usize = count
|
|
if start > std.mem.len(items) {
|
|
start = std.mem.len(items)
|
|
}
|
|
return items[start..]
|
|
}
|
|
|
|
fn __zero_std_url_is_unreserved(byte: u8) -> Bool {
|
|
return byte >= 65_u8 && byte <= 90_u8 || byte >= 97_u8 && byte <= 122_u8 || byte >= 48_u8 && byte <= 57_u8 || byte == 45_u8 || byte == 46_u8 || byte == 95_u8 || byte == 126_u8
|
|
}
|
|
|
|
fn __zero_std_url_hex_char(value: u8) -> u8 {
|
|
if value < 10_u8 {
|
|
return 48_u8 + value
|
|
}
|
|
return 65_u8 + value - 10_u8
|
|
}
|
|
|
|
fn __zero_std_url_percent_encode(buffer: MutSpan<u8>, text: Span<u8>) -> Maybe<Span<u8>> {
|
|
var input: usize = 0
|
|
var output: usize = 0
|
|
while input < std.mem.len(text) {
|
|
let byte: u8 = text[input]
|
|
if __zero_std_url_is_unreserved(byte) {
|
|
if output >= std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[output] = byte
|
|
output = output + 1
|
|
} else {
|
|
if output + 3 > std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[output] = 37_u8
|
|
buffer[output + 1] = __zero_std_url_hex_char(byte / 16_u8)
|
|
buffer[output + 2] = __zero_std_url_hex_char(byte % 16_u8)
|
|
output = output + 3
|
|
}
|
|
input = input + 1
|
|
}
|
|
return buffer[..output]
|
|
}
|
|
|
|
fn __zero_std_url_percent_decode(buffer: MutSpan<u8>, text: Span<u8>) -> Maybe<Span<u8>> {
|
|
var input: usize = 0
|
|
var output: usize = 0
|
|
while input < std.mem.len(text) {
|
|
if output >= std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
let byte: u8 = text[input]
|
|
if byte == 37_u8 {
|
|
if input + 2 >= std.mem.len(text) {
|
|
return null
|
|
}
|
|
let high: Maybe<u8> = std.ascii.hexValue(text[input + 1])
|
|
let low: Maybe<u8> = std.ascii.hexValue(text[input + 2])
|
|
if !high.has || !low.has {
|
|
return null
|
|
}
|
|
buffer[output] = high.value * 16_u8 + low.value
|
|
input = input + 3
|
|
} else {
|
|
buffer[output] = byte
|
|
input = input + 1
|
|
}
|
|
output = output + 1
|
|
}
|
|
return buffer[..output]
|
|
}
|
|
|
|
fn __zero_std_url_query_escape(buffer: MutSpan<u8>, text: Span<u8>) -> Maybe<Span<u8>> {
|
|
var input: usize = 0
|
|
var output: usize = 0
|
|
while input < std.mem.len(text) {
|
|
let byte: u8 = text[input]
|
|
if byte == 32_u8 {
|
|
if output >= std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[output] = 43_u8
|
|
output = output + 1
|
|
} else if __zero_std_url_is_unreserved(byte) {
|
|
if output >= std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[output] = byte
|
|
output = output + 1
|
|
} else {
|
|
if output + 3 > std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[output] = 37_u8
|
|
buffer[output + 1] = __zero_std_url_hex_char(byte / 16_u8)
|
|
buffer[output + 2] = __zero_std_url_hex_char(byte % 16_u8)
|
|
output = output + 3
|
|
}
|
|
input = input + 1
|
|
}
|
|
return buffer[..output]
|
|
}
|
|
|
|
fn __zero_std_url_query_unescape(buffer: MutSpan<u8>, text: Span<u8>) -> Maybe<Span<u8>> {
|
|
var input: usize = 0
|
|
var output: usize = 0
|
|
while input < std.mem.len(text) {
|
|
if output >= std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
let byte: u8 = text[input]
|
|
if byte == 43_u8 {
|
|
buffer[output] = 32_u8
|
|
input = input + 1
|
|
} else if byte == 37_u8 {
|
|
if input + 2 >= std.mem.len(text) {
|
|
return null
|
|
}
|
|
let high: Maybe<u8> = std.ascii.hexValue(text[input + 1])
|
|
let low: Maybe<u8> = std.ascii.hexValue(text[input + 2])
|
|
if !high.has || !low.has {
|
|
return null
|
|
}
|
|
buffer[output] = high.value * 16_u8 + low.value
|
|
input = input + 3
|
|
} else {
|
|
buffer[output] = byte
|
|
input = input + 1
|
|
}
|
|
output = output + 1
|
|
}
|
|
return buffer[..output]
|
|
}
|
|
|
|
fn __zero_std_url_scheme(url: Span<u8>) -> Maybe<Span<u8>> {
|
|
var index: usize = 0
|
|
while index < std.mem.len(url) {
|
|
let byte: u8 = url[index]
|
|
if byte == 58_u8 {
|
|
if index == 0 {
|
|
return null
|
|
}
|
|
return url[..index]
|
|
}
|
|
if byte == 47_u8 || byte == 63_u8 || byte == 35_u8 {
|
|
return null
|
|
}
|
|
index = index + 1
|
|
}
|
|
return null
|
|
}
|
|
|
|
fn __zero_std_url_authority_start(url: Span<u8>) -> Maybe<usize> {
|
|
let scheme: Maybe<Span<u8>> = __zero_std_url_scheme(url)
|
|
if !scheme.has {
|
|
return null
|
|
}
|
|
let start: usize = std.mem.len(scheme.value) + 1
|
|
if start + 1 >= std.mem.len(url) || url[start] != 47_u8 || url[start + 1] != 47_u8 {
|
|
return null
|
|
}
|
|
return start + 2
|
|
}
|
|
|
|
fn __zero_std_url_authority(url: Span<u8>) -> Maybe<Span<u8>> {
|
|
let start: Maybe<usize> = __zero_std_url_authority_start(url)
|
|
if !start.has {
|
|
return null
|
|
}
|
|
var end: usize = start.value
|
|
while end < std.mem.len(url) && url[end] != 47_u8 && url[end] != 63_u8 && url[end] != 35_u8 {
|
|
end = end + 1
|
|
}
|
|
if end == start.value {
|
|
return null
|
|
}
|
|
return url[start.value..end]
|
|
}
|
|
|
|
fn __zero_std_url_host(url: Span<u8>) -> Maybe<Span<u8>> {
|
|
let authority: Maybe<Span<u8>> = __zero_std_url_authority(url)
|
|
if !authority.has {
|
|
return null
|
|
}
|
|
var start: usize = 0
|
|
var index: usize = 0
|
|
while index < std.mem.len(authority.value) {
|
|
if authority.value[index] == 64_u8 {
|
|
start = index + 1
|
|
}
|
|
index = index + 1
|
|
}
|
|
if start < std.mem.len(authority.value) && authority.value[start] == 91_u8 {
|
|
var close: usize = start + 1
|
|
while close < std.mem.len(authority.value) && authority.value[close] != 93_u8 {
|
|
close = close + 1
|
|
}
|
|
if close >= std.mem.len(authority.value) || close == start + 1 {
|
|
return null
|
|
}
|
|
if close + 1 < std.mem.len(authority.value) && authority.value[close + 1] != 58_u8 {
|
|
return null
|
|
}
|
|
return authority.value[start..close + 1]
|
|
}
|
|
var end: usize = start
|
|
while end < std.mem.len(authority.value) && authority.value[end] != 58_u8 {
|
|
end = end + 1
|
|
}
|
|
if end == start {
|
|
return null
|
|
}
|
|
return authority.value[start..end]
|
|
}
|
|
|
|
fn __zero_std_url_path(url: Span<u8>) -> Span<u8> {
|
|
var start: usize = 0
|
|
let scheme: Maybe<Span<u8>> = __zero_std_url_scheme(url)
|
|
let authority_start: Maybe<usize> = __zero_std_url_authority_start(url)
|
|
if authority_start.has {
|
|
start = authority_start.value
|
|
while start < std.mem.len(url) && url[start] != 47_u8 && url[start] != 63_u8 && url[start] != 35_u8 {
|
|
start = start + 1
|
|
}
|
|
} else if scheme.has {
|
|
start = std.mem.len(scheme.value) + 1
|
|
}
|
|
if start >= std.mem.len(url) {
|
|
return url[std.mem.len(url)..]
|
|
}
|
|
var end: usize = start
|
|
while end < std.mem.len(url) && url[end] != 63_u8 && url[end] != 35_u8 {
|
|
end = end + 1
|
|
}
|
|
return url[start..end]
|
|
}
|
|
|
|
fn __zero_std_url_query(url: Span<u8>) -> Maybe<Span<u8>> {
|
|
var start: usize = 0
|
|
while start < std.mem.len(url) && url[start] != 63_u8 {
|
|
if url[start] == 35_u8 {
|
|
return null
|
|
}
|
|
start = start + 1
|
|
}
|
|
if start >= std.mem.len(url) {
|
|
return null
|
|
}
|
|
start = start + 1
|
|
var end: usize = start
|
|
while end < std.mem.len(url) && url[end] != 35_u8 {
|
|
end = end + 1
|
|
}
|
|
return url[start..end]
|
|
}
|
|
|
|
fn __zero_std_url_query_value(query: Span<u8>, key: Span<u8>) -> Maybe<Span<u8>> {
|
|
var start: usize = 0
|
|
while start <= std.mem.len(query) {
|
|
var end: usize = start
|
|
while end < std.mem.len(query) && query[end] != 38_u8 {
|
|
end = end + 1
|
|
}
|
|
var eq: usize = start
|
|
while eq < end && query[eq] != 61_u8 {
|
|
eq = eq + 1
|
|
}
|
|
let name: Span<u8> = query[start..eq]
|
|
if std.mem.eql(name, key) {
|
|
if eq < end {
|
|
return query[eq + 1..end]
|
|
}
|
|
return query[end..end]
|
|
}
|
|
if end == std.mem.len(query) {
|
|
return null
|
|
}
|
|
start = end + 1
|
|
}
|
|
return null
|
|
}
|
|
|
|
fn __zero_std_url_write_query_param(buffer: MutSpan<u8>, key: Span<u8>, value: Span<u8>) -> Maybe<Span<u8>> {
|
|
var output: usize = 0
|
|
let encoded_key: Maybe<Span<u8>> = __zero_std_url_query_escape(buffer, key)
|
|
if !encoded_key.has {
|
|
return null
|
|
}
|
|
output = output + std.mem.len(encoded_key.value)
|
|
if output >= std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
buffer[output] = 61_u8
|
|
output = output + 1
|
|
let encoded_value: Maybe<Span<u8>> = __zero_std_url_query_escape(buffer[output..], value)
|
|
if !encoded_value.has {
|
|
return null
|
|
}
|
|
output = output + std.mem.len(encoded_value.value)
|
|
return buffer[..output]
|
|
}
|
|
|
|
fn __zero_std_url_append_query(buffer: MutSpan<u8>, base: Span<u8>, query: Span<u8>) -> Maybe<Span<u8>> {
|
|
let base_len: usize = std.mem.len(base)
|
|
if base_len >= std.mem.len(buffer) {
|
|
return null
|
|
}
|
|
if std.mem.len(query) > std.mem.len(buffer) - base_len - 1 {
|
|
return null
|
|
}
|
|
var fragment: usize = 0
|
|
while fragment < base_len && base[fragment] != 35_u8 {
|
|
fragment = fragment + 1
|
|
}
|
|
var output: usize = 0
|
|
while output < fragment {
|
|
buffer[output] = base[output]
|
|
output = output + 1
|
|
}
|
|
var separator: u8 = 63_u8
|
|
var index: usize = 0
|
|
while index < fragment {
|
|
if base[index] == 63_u8 {
|
|
separator = 38_u8
|
|
}
|
|
index = index + 1
|
|
}
|
|
buffer[output] = separator
|
|
output = output + 1
|
|
var query_index: usize = 0
|
|
while query_index < std.mem.len(query) {
|
|
buffer[output] = query[query_index]
|
|
output = output + 1
|
|
query_index = query_index + 1
|
|
}
|
|
var fragment_index: usize = fragment
|
|
while fragment_index < base_len {
|
|
buffer[output] = base[fragment_index]
|
|
output = output + 1
|
|
fragment_index = fragment_index + 1
|
|
}
|
|
return buffer[..output]
|
|
}
|