84 col_index = next_column_index
85 value = read
86 if value.is_a?(T)
87 value
88 else
89 raise DB::ColumnTypeMismatchError.new(
90 context: "#{self.class}#read",
91 column_index: col_index,
92 column_name: column_name(col_index),
93 column_type: value.class.to_s,
94 expected_type: T.to_s
636 sgrnt_p = rs.read(String)
637 stabbr = rs.read(String)
638 state = rs.read(String)
639 tuition2_fee2 = rs.read(String)
640 tuition3_fee3 = rs.read(String)
641 webaddr = rs.read(String)
642 zip = rs.read(String)
643 admssn = rs.read(String)
644 applcn = rs.read(String)
645 gentele = rs.read(String)
646 stars = rs.read(String)
7 getter method, path, handler
8 @handler : HTTP::Server::Context -> String
9
10 def initialize(@method : String, @path : String, &handler : HTTP::Server::Context -> _)
11 @handler = ->(context : HTTP::Server::Context) do
12 output = handler.call(context)
13 output.is_a?(String) ? output : ""
14 end
15 end
16 end
17end
44
45 # Processes the route if it's a match. Otherwise renders 404.
46 private def process_request(context)
47 raise Kemal::Exceptions::RouteNotFound.new(context) unless context.route_found?
48 return if context.response.closed?
49 content = context.route.handler.call(context)
50
51 if !Kemal.config.error_handlers.empty? && Kemal.config.error_handlers.has_key?(context.response.status_code)
52 raise Kemal::Exceptions::CustomException.new(context)
53 end
54
12 @routes = Radix::Tree(Route).new
13 @cached_routes = Hash(String, Radix::Result(Route)).new
14 end
15
16 def call(context : HTTP::Server::Context)
17 process_request(context)
18 end
19
20 # Adds a given route to routing tree. As an exception each `GET` route additionaly defines
21 # a corresponding `HEAD` route.
22 def add_route(method : String, path : String, &handler : HTTP::Server::Context -> _)
23
24 abstract def call(context : HTTP::Server::Context)
25
26 def call_next(context : HTTP::Server::Context)
27 if next_handler = @next
28 next_handler.call(context)
29 else
30 context.response.respond_with_status(:not_found)
31 end
32 end
33
8 def initialize
9 @routes = Radix::Tree(WebSocket).new
10 end
11
12 def call(context : HTTP::Server::Context)
13 return call_next(context) unless context.ws_route_found? && websocket_upgrade_request?(context)
14 context.websocket.call(context)
15 end
16
17 def lookup_ws_route(path : String)
18 @routes.find "/ws" + path
23
24 abstract def call(context : HTTP::Server::Context)
25
26 def call_next(context : HTTP::Server::Context)
27 if next_handler = @next
28 next_handler.call(context)
29 else
30 context.response.respond_with_status(:not_found)
31 end
32 end
33
70 context.response.status_code = 304
71 return
72 end
73 send_file(context, file_path)
74 else
75 call_next(context)
76 end
77 end
78
79 private def modification_time(file_path)
80 File.info(file_path).modification_time
23
24 abstract def call(context : HTTP::Server::Context)
25
26 def call_next(context : HTTP::Server::Context)
27 if next_handler = @next
28 next_handler.call(context)
29 else
30 context.response.respond_with_status(:not_found)
31 end
32 end
33
3 class ExceptionHandler
4 include HTTP::Handler
5 INSTANCE = new
6
7 def call(context : HTTP::Server::Context)
8 call_next(context)
9 rescue ex : Kemal::Exceptions::RouteNotFound
10 call_exception_with_status_code(context, ex, 404)
11 rescue ex : Kemal::Exceptions::CustomException
12 call_exception_with_status_code(context, ex, context.response.status_code)
13 rescue ex : Exception
23
24 abstract def call(context : HTTP::Server::Context)
25
26 def call_next(context : HTTP::Server::Context)
27 if next_handler = @next
28 next_handler.call(context)
29 else
30 context.response.respond_with_status(:not_found)
31 end
32 end
33
352 # elapsed_time # => 20.milliseconds (approximately)
353 # ```
354 def self.measure(&block : ->) : Time::Span
355 start = monotonic
356 yield
357 monotonic - start
358 end
359
360 # Creates a new `Time` instance representing the current time from the
361 # system clock observed in *location* (defaults to local time zone).
362 def self.local(location : Location = Location.local) : Time
23
24 abstract def call(context : HTTP::Server::Context)
25
26 def call_next(context : HTTP::Server::Context)
27 if next_handler = @next
28 next_handler.call(context)
29 else
30 context.response.respond_with_status(:not_found)
31 end
32 end
33
7 INSTANCE = new
8
9 def call(context : HTTP::Server::Context)
10 context.response.headers.add "X-Powered-By", "Kemal" if Kemal.config.powered_by_header
11 context.response.content_type = "text/html" unless context.response.headers.has_key?("Content-Type")
12 call_next context
13 end
14 end
15end
46 response.version = request.version
47 response.headers["Connection"] = "keep-alive" if request.keep_alive?
48 context = Context.new(request, response)
49
50 Log.with_context do
51 @handler.call(context)
52 rescue ex : ClientError
53 Log.debug(exception: ex.cause) { ex.message }
54 rescue ex
55 Log.error(exception: ex) { "Unhandled exception on HTTP::Handler" }
56 unless response.closed?
510 return
511 end
512 end
513 {% end %}
514
515 @processor.process(io, io)
516 ensure
517 {% begin %}
518 begin
519 io.close
520 rescue IO::Error{% unless flag?(:without_openssl) %} | OpenSSL::SSL::Error{% end %}
463 end
464
465 if io
466 # a non nillable version of the closured io
467 _io = io
468 spawn handle_client(_io)
469 else
470 break
471 end
472 end
473 ensure
141 end
142
143 # :nodoc:
144 def run
145 GC.unlock_read
146 @proc.call
147 rescue ex
148 if name = @name
149 STDERR.print "Unhandled exception in spawn(name: #{name}): "
150 else
151 STDERR.print "Unhandled exception in spawn: "
93 {Pointer(Void).null, Pointer(Void).null}
94 {% else %}
95 Fiber.stack_pool.checkout
96 {% end %}
97
98 fiber_main = ->(f : Fiber) { f.run }
99
100 # FIXME: This line shouldn't be necessary (#7975)
101 stack_ptr = nil
102 {% if flag?(:win32) %}
103 # align stack bottom to 16 bytes