Added more methods to process various types of post forms

This commit is contained in:
Yessiest 2023-10-25 10:49:58 +04:00
parent 9030b5ef05
commit 59aa1206ff
2 changed files with 55 additions and 9 deletions

View File

@ -4,6 +4,7 @@ require_relative '../response'
require_relative '../util/multipart' require_relative '../util/multipart'
require_relative '../util/parseutils' require_relative '../util/parseutils'
require_relative '../util/html' require_relative '../util/html'
require 'json'
module Landline module Landline
module DSL module DSL
@ -85,18 +86,12 @@ module Landline
# Checks if current request has multipart/form-data associated with it # Checks if current request has multipart/form-data associated with it
# @return [Boolean] # @return [Boolean]
def form? def form?
value, opts = Landline::Util::ParserCommon.parse_value( value, opts = _verify_content_type('multipart/form-data')
request.headers["content-type"] !!(value && opts && opts['boundary'])
)
if value == "multipart/form-data" and
opts["boundary"]
true
else
false
end
end end
# Returns formdata # Returns formdata
# @note reads request.input - may nullify request.body.
# @return [Hash{String=>(String,Landline::Util::FormPart)}] # @return [Hash{String=>(String,Landline::Util::FormPart)}]
def form def form
_, opts = Landline::Util::ParserCommon.parse_value( _, opts = Landline::Util::ParserCommon.parse_value(
@ -107,6 +102,39 @@ module Landline
).to_h ).to_h
end end
# Checks if current request has urlencoded query string
# @return [Boolean]
def query?
!!_verify_content_type("application/x-www-form-urlencode")
end
# Returns parsed query hash
# @note reads request.body - may nullify .input, .body data is memoized
# @return [Hash{String => Object}] query data
def query
Landline::Util::Query.new(request.body).parse
end
# Returns shallow parsed query hash
# @note reads request.body - may nullify .input, .body data is memoized
# @return [Hash{String => Object}] query data
def query_shallow
Landline::Util::Query.new(request.body).parse_shallow
end
# Check if body is a JSON object
# @return [Boolean]
def json?
!!_verify_content_type('application/json')
end
# Return parse JSON object
# @note reads request.input - may nullify request.body.
# @return [Object]
def json
JSON.load(request.input)
end
# Open a file relative to current filepath # Open a file relative to current filepath
# @see File.open # @see File.open
def file(path, mode = "r", *all, &block) def file(path, mode = "r", *all, &block)
@ -124,6 +152,22 @@ module Landline
def unescape_html(text) def unescape_html(text)
Landline::Util.unescape_html(text) Landline::Util.unescape_html(text)
end end
private
def _verify_content_type(type)
return false unless request.headers['content-type']
value, opts = Landline::Util::ParserCommon.parse_value(
request.headers["content-type"]
)
if value == type and
request.input
[value, opts]
else
false
end
end
end end
end end
end end

View File

@ -41,12 +41,14 @@ module Landline
end end
# Returns request body (if POST data exists) # Returns request body (if POST data exists)
# @note reads data from rack.input, which is not rewindable. .body data is memoized.
# @return [nil, String] # @return [nil, String]
def body def body
@body ||= @rack.input&.read @body ||= @rack.input&.read
end end
# Returns raw Rack input object # Returns raw Rack input object
# @note Rack IO is not always rewindable - if it is read once, the data is gone (i.e. request.body will return nothing).
# @return [IO] (May not entirely be compatible with IO, see Rack/SPEC.rdoc) # @return [IO] (May not entirely be compatible with IO, see Rack/SPEC.rdoc)
def input def input
@rack.input @rack.input