From 0e9f8ab3a51f3f87243c5f18f041efb44943f939 Mon Sep 17 00:00:00 2001 From: Oleh Prypin <oleh@pryp.in> Date: Sat, 3 Apr 2021 11:56:13 +0200 Subject: [PATCH 1/3] Add return type restrictions to HTTP-related classes --- src/http/client/response.cr | 14 +++++++------- src/http/common.cr | 12 ++++++------ src/http/cookie.cr | 32 ++++++++++++++++---------------- src/http/formdata/builder.cr | 2 +- src/http/formdata/parser.cr | 2 +- src/http/headers.cr | 32 ++++++++++++++++---------------- src/http/request.cr | 16 ++++++++-------- src/http/server/response.cr | 4 ++-- src/http/web_socket/protocol.cr | 2 +- src/mime/media_type.cr | 6 +++--- src/mime/multipart.cr | 2 +- src/mime/multipart/builder.cr | 2 +- src/mime/multipart/parser.cr | 2 +- src/socket.cr | 20 ++++++++++---------- src/socket/address.cr | 8 ++++---- src/socket/addrinfo.cr | 2 +- src/socket/ip_socket.cr | 4 ++-- src/socket/tcp_socket.cr | 2 +- src/socket/udp_socket.cr | 4 ++-- src/socket/unix_socket.cr | 6 +++--- src/uri.cr | 6 +++--- src/uri/params.cr | 12 ++++++------ src/uri/punycode.cr | 6 +++--- src/uri/uri_parser.cr | 4 ++-- 24 files changed, 101 insertions(+), 101 deletions(-) diff --git a/src/http/client/response.cr b/src/http/client/response.cr index 3b81b523eb84..6ece2a4211ae 100644 --- a/src/http/client/response.cr +++ b/src/http/client/response.cr @@ -25,26 +25,26 @@ class HTTP::Client::Response new(HTTP::Status.new(status_code), body, headers, status_message, version, body_io) end - def body + def body : String @body || "" end - def body? + def body? : String? @body end # Returns `true` if the response status code is between 200 and 299. - def success? + def success? : Bool @status.success? end # Returns a convenience wrapper around querying and setting cookie related # headers, see `HTTP::Cookies`. - def cookies + def cookies : HTTP::Cookies @cookies ||= Cookies.from_server_headers(headers) end - def keep_alive? + def keep_alive? : Bool HTTP.keep_alive?(self) end @@ -53,7 +53,7 @@ class HTTP::Client::Response end # Convenience method to retrieve the HTTP status code. - def status_code + def status_code : Int32 status.code end @@ -98,7 +98,7 @@ class HTTP::Client::Response # Parses an `HTTP::Client::Response` from the given `IO`. # Might return `nil` if there's no data in the `IO`, # which probably means that the connection was closed. - def self.from_io?(io, ignore_body = false, decompress = true) + def self.from_io?(io, ignore_body = false, decompress = true) : self? from_io?(io, ignore_body: ignore_body, decompress: decompress) do |response| if response response.consume_body_io diff --git a/src/http/common.cr b/src/http/common.cr index ad2288fae67e..33b6a1705e8d 100644 --- a/src/http/common.cr +++ b/src/http/common.cr @@ -243,7 +243,7 @@ module HTTP ) # :nodoc: - def self.header_name(slice : Bytes) + def self.header_name(slice : Bytes) : String # Check if the header name is a common one. # If so we avoid having to allocate a string for it. if slice.size < 20 @@ -306,7 +306,7 @@ module HTTP end # :nodoc: - def self.content_length(headers) + def self.content_length(headers) : UInt64? length_headers = headers.get? "Content-Length" return nil unless length_headers first_header = length_headers[0] @@ -317,7 +317,7 @@ module HTTP end # :nodoc: - def self.keep_alive?(message) + def self.keep_alive?(message) : Bool case message.headers["Connection"]?.try &.downcase when "keep-alive" true @@ -333,7 +333,7 @@ module HTTP end end - def self.expect_continue?(headers) + def self.expect_continue?(headers) : Bool headers["Expect"]?.try(&.downcase) == "100-continue" end @@ -379,7 +379,7 @@ module HTTP # quoted = %q(\"foo\\bar\") # HTTP.dequote_string(quoted) # => %q("foo\bar") # ``` - def self.dequote_string(str) + def self.dequote_string(str) : String data = str.to_slice quoted_pair_index = data.index('\\'.ord) return str unless quoted_pair_index @@ -434,7 +434,7 @@ module HTTP # string = %q("foo\ bar") # HTTP.quote_string(string) # => %q(\"foo\\\ bar\") # ``` - def self.quote_string(string) + def self.quote_string(string) : String String.build do |io| quote_string(string, io) end diff --git a/src/http/cookie.cr b/src/http/cookie.cr index c86a16bdf7e7..77ef34230eeb 100644 --- a/src/http/cookie.cr +++ b/src/http/cookie.cr @@ -78,7 +78,7 @@ module HTTP end end - def to_set_cookie_header + def to_set_cookie_header : String path = @path expires = @expires domain = @domain @@ -95,7 +95,7 @@ module HTTP end end - def to_cookie_header + def to_cookie_header : String String.build do |io| to_cookie_header(io) end @@ -107,7 +107,7 @@ module HTTP io << @value end - def expired? + def expired? : Bool if e = expires e <= Time.utc else @@ -156,13 +156,13 @@ module HTTP end end - def parse_cookies(header) + def parse_cookies(header) : Array(HTTP::Cookie) cookies = [] of Cookie parse_cookies(header) { |cookie| cookies << cookie } cookies end - def parse_set_cookie(header) + def parse_set_cookie(header) : HTTP::Cookie? match = header.match(SetCookieString) return unless match @@ -224,7 +224,7 @@ module HTTP end # Filling cookies by parsing the `Cookie` headers in the given `HTTP::Headers`. - def fill_from_client_headers(headers) + def fill_from_client_headers(headers) : self if values = headers.get?("Cookie") values.each do |header| Cookie::Parser.parse_cookies(header) { |cookie| self << cookie } @@ -241,7 +241,7 @@ module HTTP end # Filling cookies by parsing the `Set-Cookie` headers in the given `HTTP::Headers`. - def fill_from_server_headers(headers) + def fill_from_server_headers(headers) : self if values = headers.get?("Set-Cookie") values.each do |header| Cookie::Parser.parse_set_cookie(header).try { |cookie| self << cookie } @@ -292,7 +292,7 @@ module HTTP # ``` # request.cookies["foo"].value # => "bar" # ``` - def [](key) + def [](key) : HTTP::Cookie @cookies[key] end @@ -306,7 +306,7 @@ module HTTP # request.cookies["foo"] = "bar" # request.cookies["foo"]?.try &.value # > "bar" # ``` - def []?(key) + def []?(key) : HTTP::Cookie? @cookies[key]? end @@ -315,7 +315,7 @@ module HTTP # ``` # request.cookies.has_key?("foo") # => true # ``` - def has_key?(key) + def has_key?(key) : Bool @cookies.has_key?(key) end @@ -325,19 +325,19 @@ module HTTP # ``` # response.cookies << HTTP::Cookie.new("foo", "bar", http_only: true) # ``` - def <<(cookie : Cookie) + def <<(cookie : Cookie) : HTTP::Cookie self[cookie.name] = cookie end # Clears the collection, removing all cookies. - def clear + def clear : Hash(String, HTTP::Cookie) @cookies.clear end # Deletes and returns the `HTTP::Cookie` for the specified *key*, or # returns `nil` if *key* cannot be found in the collection. Note that # *key* should match the name attribute of the desired `HTTP::Cookie`. - def delete(key) + def delete(key) : HTTP::Cookie? @cookies.delete(key) end @@ -354,12 +354,12 @@ module HTTP end # Returns the number of cookies contained in this collection. - def size + def size : Int32 @cookies.size end # Whether the collection contains any cookies. - def empty? + def empty? : Bool @cookies.empty? end @@ -393,7 +393,7 @@ module HTTP end # Returns this collection as a plain `Hash`. - def to_h + def to_h : Hash(String, HTTP::Cookie) @cookies.dup end end diff --git a/src/http/formdata/builder.cr b/src/http/formdata/builder.cr index 5947dc06724b..983451f25865 100644 --- a/src/http/formdata/builder.cr +++ b/src/http/formdata/builder.cr @@ -29,7 +29,7 @@ module HTTP::FormData # builder = HTTP::FormData::Builder.new(io, "a4VF") # builder.content_type # => "multipart/form-data; boundary=\"a4VF\"" # ``` - def content_type + def content_type : String String.build do |str| str << "multipart/form-data; boundary=\"" HTTP.quote_string(@boundary, str) diff --git a/src/http/formdata/parser.cr b/src/http/formdata/parser.cr index 49b935b4ec80..e93f2b029e6c 100644 --- a/src/http/formdata/parser.cr +++ b/src/http/formdata/parser.cr @@ -38,7 +38,7 @@ module HTTP::FormData end # True if `#next` can be called legally. - def has_next? + def has_next? : Bool @multipart.has_next? end end diff --git a/src/http/headers.cr b/src/http/headers.cr index 6bbc8063897c..d8823a9aa0b2 100644 --- a/src/http/headers.cr +++ b/src/http/headers.cr @@ -67,12 +67,12 @@ struct HTTP::Headers @hash[wrap(key)] = value end - def [](key) + def [](key) : String values = @hash[wrap(key)] concat values end - def []?(key) + def []?(key) : String? fetch(key, nil) end @@ -85,7 +85,7 @@ struct HTTP::Headers # headers = HTTP::Headers{"Connection" => "keep-alive, Upgrade"} # headers.includes_word?("Connection", "Upgrade") # => true # ``` - def includes_word?(key, word) + def includes_word?(key, word) : Bool return false if word.empty? values = @hash[wrap(key)]? @@ -118,31 +118,31 @@ struct HTTP::Headers false end - def add(key, value : String) + def add(key, value : String) : self check_invalid_header_content value unsafe_add(key, value) self end - def add(key, value : Array(String)) + def add(key, value : Array(String)) : self value.each { |val| check_invalid_header_content val } unsafe_add(key, value) self end - def add?(key, value : String) + def add?(key, value : String) : Bool return false unless valid_value?(value) unsafe_add(key, value) true end - def add?(key, value : Array(String)) + def add?(key, value : Array(String)) : Bool value.each { |val| return false unless valid_value?(val) } unsafe_add(key, value) true end - def fetch(key, default) + def fetch(key, default) : String? fetch(wrap(key)) { default } end @@ -151,20 +151,20 @@ struct HTTP::Headers values ? concat(values) : yield key end - def has_key?(key) + def has_key?(key) : Bool @hash.has_key? wrap(key) end - def empty? + def empty? : Bool @hash.empty? end - def delete(key) + def delete(key) : String? values = @hash.delete wrap(key) values ? concat(values) : nil end - def merge!(other) + def merge!(other) : self other.each do |key, value| self[wrap(key)] = value end @@ -233,11 +233,11 @@ struct HTTP::Headers end end - def get(key) + def get(key) : Array(String) cast @hash[wrap(key)] end - def get?(key) + def get?(key) : Array(String)? @hash[wrap(key)]?.try { |value| cast(value) } end @@ -253,7 +253,7 @@ struct HTTP::Headers dup end - def same?(other : HTTP::Headers) + def same?(other : HTTP::Headers) : Bool object_id == other.object_id end @@ -299,7 +299,7 @@ struct HTTP::Headers end end - def valid_value?(value) + def valid_value?(value) : Bool return invalid_value_char(value).nil? end diff --git a/src/http/request.cr b/src/http/request.cr index c7547bd4ad3c..324e05c23542 100644 --- a/src/http/request.cr +++ b/src/http/request.cr @@ -57,26 +57,26 @@ class HTTP::Request # Returns a convenience wrapper around querying and setting cookie related # headers, see `HTTP::Cookies`. - def cookies + def cookies : HTTP::Cookies @cookies ||= Cookies.from_client_headers(headers) end # Returns a convenience wrapper around querying and setting query params, # see `URI::Params`. - def query_params + def query_params : URI::Params @query_params ||= uri.query_params end - def resource + def resource : String update_uri @uri.try(&.request_target) || @resource end - def keep_alive? + def keep_alive? : Bool HTTP.keep_alive?(self) end - def ignore_body? + def ignore_body? : Bool @method == "HEAD" end @@ -237,7 +237,7 @@ class HTTP::Request end # Returns the request's path component. - def path + def path : String uri.path.presence || "/" end @@ -247,7 +247,7 @@ class HTTP::Request end # Lazily parses and returns the request's query component. - def query + def query : String? update_uri uri.query end @@ -287,7 +287,7 @@ class HTTP::Request # Returns request host with port from headers. @[Deprecated(%q(Use `headers["Host"]?` instead.))] - def host_with_port + def host_with_port : String? @headers["Host"]? end diff --git a/src/http/server/response.cr b/src/http/server/response.cr index 6d0eef046126..f68046a702aa 100644 --- a/src/http/server/response.cr +++ b/src/http/server/response.cr @@ -69,7 +69,7 @@ class HTTP::Server end # Convenience method to retrieve the HTTP status code. - def status_code + def status_code : Int32 status.code end @@ -87,7 +87,7 @@ class HTTP::Server end # Convenience method to set cookies, see `HTTP::Cookies`. - def cookies + def cookies : HTTP::Cookies @cookies ||= HTTP::Cookies.new end diff --git a/src/http/web_socket/protocol.cr b/src/http/web_socket/protocol.cr index 6075c67453cf..b190ebb25d03 100644 --- a/src/http/web_socket/protocol.cr +++ b/src/http/web_socket/protocol.cr @@ -106,7 +106,7 @@ class HTTP::WebSocket::Protocol @io.flush if flush end - def receive(buffer : Bytes) + def receive(buffer : Bytes) : HTTP::WebSocket::Protocol::PacketInfo if @remaining == 0 opcode = read_header else diff --git a/src/mime/media_type.cr b/src/mime/media_type.cr index 8d96b782fb98..3d692d3ae421 100644 --- a/src/mime/media_type.cr +++ b/src/mime/media_type.cr @@ -77,7 +77,7 @@ module MIME # MIME::MediaType.parse("x-application/example").fetch("foo", "baz") # => "baz" # MIME::MediaType.parse("x-application/example; foo=bar").fetch("foo", "baz") # => "bar" # ``` - def fetch(key : String, default) + def fetch(key : String, default : T) : String | T forall T @params.fetch(key, default) end @@ -483,12 +483,12 @@ module MIME end # :nodoc: - def self.token?(char : Char) + def self.token?(char : Char) : Bool !TSPECIAL_CHARACTERS.includes?(char) && 0x20 <= char.ord < 0x7F end # :nodoc: - def self.token?(string) + def self.token?(string) : Bool string.each_char.all? { |char| token? char } end diff --git a/src/mime/multipart.cr b/src/mime/multipart.cr index f5f86da3508a..179a7b92790e 100644 --- a/src/mime/multipart.cr +++ b/src/mime/multipart.cr @@ -39,7 +39,7 @@ module MIME::Multipart # # MIME::Multipart.parse_boundary("multipart/mixed; boundary=\"abcde\"") # => "abcde" # ``` - def self.parse_boundary(content_type) + def self.parse_boundary(content_type) : String? type = MIME::MediaType.parse?(content_type) if type && type.type == "multipart" diff --git a/src/mime/multipart/builder.cr b/src/mime/multipart/builder.cr index 202406880103..e96d6fe121b1 100644 --- a/src/mime/multipart/builder.cr +++ b/src/mime/multipart/builder.cr @@ -33,7 +33,7 @@ module MIME::Multipart # builder = MIME::Multipart::Builder.new(io, "a4VF") # builder.content_type("mixed") # => "multipart/mixed; boundary=a4VF" # ``` - def content_type(subtype = "mixed") + def content_type(subtype = "mixed") : String MIME::MediaType.new("multipart/#{subtype}", {"boundary" => @boundary}).to_s end diff --git a/src/mime/multipart/parser.cr b/src/mime/multipart/parser.cr index aebe99db4129..97e4be756d27 100644 --- a/src/mime/multipart/parser.cr +++ b/src/mime/multipart/parser.cr @@ -79,7 +79,7 @@ module MIME::Multipart end # True if `#next` can be called legally. - def has_next? + def has_next? : Bool @state != :FINISHED && @state != :ERRORED end diff --git a/src/socket.cr b/src/socket.cr index 7781515f7e6e..faf1d089a679 100644 --- a/src/socket.cr +++ b/src/socket.cr @@ -68,7 +68,7 @@ class Socket < IO # Creates a TCP socket. Consider using `TCPSocket` or `TCPServer` unless you # need full control over the socket. - def self.tcp(family : Family, blocking = false) + def self.tcp(family : Family, blocking = false) : self new(family, Type::STREAM, Protocol::TCP, blocking) end @@ -80,7 +80,7 @@ class Socket < IO # Creates an UNIX socket. Consider using `UNIXSocket` or `UNIXServer` unless # you need full control over the socket. - def self.unix(type : Type = Type::STREAM, blocking = false) + def self.unix(type : Type = Type::STREAM, blocking = false) : self new(Family::UNIX, type, blocking: blocking) end @@ -256,7 +256,7 @@ class Socket < IO # socket.close # end # ``` - def accept? + def accept? : Socket? if client_fd = accept_impl sock = Socket.new(client_fd, family, type, protocol, blocking) sock.sync = sync? @@ -397,7 +397,7 @@ class Socket < IO io << "#<#{self.class}:fd #{fd}>" end - def send_buffer_size + def send_buffer_size : Int32 getsockopt LibC::SO_SNDBUF, 0 end @@ -406,7 +406,7 @@ class Socket < IO val end - def recv_buffer_size + def recv_buffer_size : Int32 getsockopt LibC::SO_RCVBUF, 0 end @@ -415,7 +415,7 @@ class Socket < IO val end - def reuse_address? + def reuse_address? : Bool getsockopt_bool LibC::SO_REUSEADDR end @@ -423,7 +423,7 @@ class Socket < IO setsockopt_bool LibC::SO_REUSEADDR, val end - def reuse_port? + def reuse_port? : Bool getsockopt(LibC::SO_REUSEPORT, 0) do |value| return value != 0 end @@ -439,7 +439,7 @@ class Socket < IO setsockopt_bool LibC::SO_REUSEPORT, val end - def broadcast? + def broadcast? : Bool getsockopt_bool LibC::SO_BROADCAST end @@ -517,13 +517,13 @@ class Socket < IO end # Returns `true` if the string represents a valid IPv4 or IPv6 address. - def self.ip?(string : String) + def self.ip?(string : String) : Bool addr = LibC::In6Addr.new ptr = pointerof(addr).as(Void*) LibC.inet_pton(LibC::AF_INET, string, ptr) > 0 || LibC.inet_pton(LibC::AF_INET6, string, ptr) > 0 end - def blocking + def blocking : Bool fcntl(LibC::F_GETFL) & LibC::O_NONBLOCK == 0 end diff --git a/src/socket/address.cr b/src/socket/address.cr index 298ca77e89bb..7a4f4c493c45 100644 --- a/src/socket/address.cr +++ b/src/socket/address.cr @@ -30,7 +30,7 @@ class Socket # * `unix://<path>` # # See `IPAddress.parse` and `UNIXAddress.parse` for details. - def self.parse(uri : URI) + def self.parse(uri : URI) : self case uri.scheme when "ip", "tcp", "udp" IPAddress.parse uri @@ -42,7 +42,7 @@ class Socket end # :ditto: - def self.parse(uri : String) + def self.parse(uri : String) : self parse URI.parse(uri) end @@ -138,7 +138,7 @@ class Socket end # :ditto: - def self.parse(uri : String) + def self.parse(uri : String) : self parse URI.parse(uri) end @@ -377,7 +377,7 @@ class Socket end # :ditto: - def self.parse(uri : String) + def self.parse(uri : String) : self parse URI.parse(uri) end diff --git a/src/socket/addrinfo.cr b/src/socket/addrinfo.cr index 9885a9b48f3d..a52984eca272 100644 --- a/src/socket/addrinfo.cr +++ b/src/socket/addrinfo.cr @@ -197,7 +197,7 @@ class Socket @ip_address : IPAddress? # Returns an `IPAddress` matching this addrinfo. - def ip_address + def ip_address : Socket::IPAddress @ip_address ||= IPAddress.from(to_unsafe, size) end diff --git a/src/socket/ip_socket.cr b/src/socket/ip_socket.cr index ea59b9fcc6c3..d406389ae67f 100644 --- a/src/socket/ip_socket.cr +++ b/src/socket/ip_socket.cr @@ -1,6 +1,6 @@ class IPSocket < Socket # Returns the `IPAddress` for the local end of the IP socket. - def local_address + def local_address : Socket::IPAddress sockaddr6 = uninitialized LibC::SockaddrIn6 sockaddr = pointerof(sockaddr6).as(LibC::Sockaddr*) addrlen = LibC::SocklenT.new(sizeof(LibC::SockaddrIn6)) @@ -13,7 +13,7 @@ class IPSocket < Socket end # Returns the `IPAddress` for the remote end of the IP socket. - def remote_address + def remote_address : Socket::IPAddress sockaddr6 = uninitialized LibC::SockaddrIn6 sockaddr = pointerof(sockaddr6).as(LibC::Sockaddr*) addrlen = LibC::SocklenT.new(sizeof(LibC::SockaddrIn6)) diff --git a/src/socket/tcp_socket.cr b/src/socket/tcp_socket.cr index cbf105c80b7b..68ec58226eae 100644 --- a/src/socket/tcp_socket.cr +++ b/src/socket/tcp_socket.cr @@ -61,7 +61,7 @@ class TCPSocket < IPSocket end # Returns `true` if the Nagle algorithm is disabled. - def tcp_nodelay? + def tcp_nodelay? : Bool getsockopt_bool LibC::TCP_NODELAY, level: Protocol::TCP end diff --git a/src/socket/udp_socket.cr b/src/socket/udp_socket.cr index 5f25c6b1ce30..bb76391529a0 100644 --- a/src/socket/udp_socket.cr +++ b/src/socket/udp_socket.cr @@ -93,7 +93,7 @@ class UDPSocket < IPSocket # Reports whether transmitted multicast packets should be copied and sent # back to the originator. - def multicast_loopback? + def multicast_loopback? : Bool case @family when Family::INET getsockopt_bool LibC::IP_MULTICAST_LOOP, LibC::IPPROTO_IP @@ -122,7 +122,7 @@ class UDPSocket < IPSocket # Multicast datagrams with a `hoplimit` of `0` will not be transmitted on any # network, but may be delivered locally if the sending host belongs to the # destination group and multicast loopback is enabled. - def multicast_hops + def multicast_hops : Int32 case @family when Family::INET getsockopt LibC::IP_MULTICAST_TTL, 0, LibC::IPPROTO_IP diff --git a/src/socket/unix_socket.cr b/src/socket/unix_socket.cr index 940b2cc3f589..2bc9caaa2ee8 100644 --- a/src/socket/unix_socket.cr +++ b/src/socket/unix_socket.cr @@ -62,7 +62,7 @@ class UNIXSocket < Socket # left.puts "message" # left.gets # => "message" # ``` - def self.pair(type : Type = Type::STREAM) + def self.pair(type : Type = Type::STREAM) : {UNIXSocket, UNIXSocket} fds = uninitialized Int32[2] socktype = type.value @@ -91,11 +91,11 @@ class UNIXSocket < Socket end end - def local_address + def local_address : Socket::UNIXAddress UNIXAddress.new(path.to_s) end - def remote_address + def remote_address : Socket::UNIXAddress UNIXAddress.new(path.to_s) end diff --git a/src/uri.cr b/src/uri.cr index d68789bf0b03..a09ad83974ed 100644 --- a/src/uri.cr +++ b/src/uri.cr @@ -183,7 +183,7 @@ class URI # URI.parse("http://[::1]/bar").hostname # => "::1" # URI.parse("http://[::1]/bar").host # => "[::1]" # ``` - def hostname + def hostname : String? host.try { |host| self.class.unwrap_ipv6(host) } end @@ -196,7 +196,7 @@ class URI # URI.unwrap_ipv6("127.0.0.1") # => "127.0.0.1" # URI.unwrap_ipv6("example.com") # => "example.com" # ``` - def self.unwrap_ipv6(host) + def self.unwrap_ipv6(host) : String if host.starts_with?('[') && host.ends_with?(']') host.byte_slice(1, host.bytesize - 2) else @@ -557,7 +557,7 @@ class URI # ``` # # The return value is URL encoded (see `#encode_www_form`). - def userinfo + def userinfo : String? if user = @user String.build { |io| userinfo(user, io) } end diff --git a/src/uri/params.cr b/src/uri/params.cr index 224dcb6dd759..9964429133e4 100644 --- a/src/uri/params.cr +++ b/src/uri/params.cr @@ -87,7 +87,7 @@ class URI # # URI::Params.encode({"foo" => "bar", "baz" => ["quux", "quuz"]}) # => "foo=bar&baz=quux&baz=quuz" # ``` - def self.encode(hash : Hash(String, String | Array(String))) + def self.encode(hash : Hash(String, String | Array(String))) : String build do |builder| hash.each do |key, value| builder.add key, value @@ -190,7 +190,7 @@ class URI # params["email"] # => "john@example.org" # params["non_existent_param"] # KeyError # ``` - def [](name) + def [](name) : String fetch(name) { raise KeyError.new "Missing param name: #{name.inspect}" } end @@ -200,7 +200,7 @@ class URI # params["email"]? # => "john@example.org" # params["non_existent_param"]? # nil # ``` - def []?(name) + def []?(name) : String? fetch(name, nil) end @@ -248,7 +248,7 @@ class URI # params.set_all("item", ["pencil", "book", "workbook"]) # params.fetch_all("item") # => ["pencil", "book", "workbook"] # ``` - def fetch_all(name) + def fetch_all(name) : Array(String) raw_params.fetch(name) { [] of String } end @@ -332,7 +332,7 @@ class URI # # params.delete("non_existent_param") # KeyError # ``` - def delete(name) + def delete(name) : String value = raw_params[name].shift raw_params.delete(name) if raw_params[name].size == 0 value @@ -346,7 +346,7 @@ class URI # params.delete_all("comments") # => ["hello, world!", ":+1:"] # params.has_key?("comments") # => false # ``` - def delete_all(name) + def delete_all(name) : Array(String)? raw_params.delete(name) end diff --git a/src/uri/punycode.cr b/src/uri/punycode.cr index 1c77610270de..7fa26ebd874d 100644 --- a/src/uri/punycode.cr +++ b/src/uri/punycode.cr @@ -26,7 +26,7 @@ class URI k + (((BASE - TMIN + 1) * delta) // (delta + SKEW)) end - def self.encode(string) + def self.encode(string) : String String.build { |io| encode string, io } end @@ -87,7 +87,7 @@ class URI end end - def self.decode(string) + def self.decode(string) : String output, _, rest = string.rpartition(DELIMITER) output = output.chars @@ -138,7 +138,7 @@ class URI output.join end - def self.to_ascii(string) + def self.to_ascii(string) : String return string if string.ascii_only? String.build do |io| diff --git a/src/uri/uri_parser.cr b/src/uri/uri_parser.cr index 52b0aeec566c..fd28b8584d71 100644 --- a/src/uri/uri_parser.cr +++ b/src/uri/uri_parser.cr @@ -18,11 +18,11 @@ class URI @ptr = 0 end - def c + def c : UInt8 @input[@ptr] end - def run + def run : self parse_scheme_start self end From 6a182f559d7ea862c4aaaeb9b843a57c3e6d2b4b Mon Sep 17 00:00:00 2001 From: Oleh Prypin <oleh@pryp.in> Date: Mon, 5 Apr 2021 15:47:49 +0200 Subject: [PATCH 2/3] Shorten a type --- src/http/web_socket/protocol.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/http/web_socket/protocol.cr b/src/http/web_socket/protocol.cr index b190ebb25d03..94f95a53a5e9 100644 --- a/src/http/web_socket/protocol.cr +++ b/src/http/web_socket/protocol.cr @@ -106,7 +106,7 @@ class HTTP::WebSocket::Protocol @io.flush if flush end - def receive(buffer : Bytes) : HTTP::WebSocket::Protocol::PacketInfo + def receive(buffer : Bytes) : PacketInfo if @remaining == 0 opcode = read_header else From a9ffbf1c016d1e8f1cef6c2df81261bbbac12bd4 Mon Sep 17 00:00:00 2001 From: Oleh Prypin <oleh@pryp.in> Date: Thu, 8 Apr 2021 21:40:10 +0200 Subject: [PATCH 3/3] Shorten a type --- src/http/cookie.cr | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/http/cookie.cr b/src/http/cookie.cr index 77ef34230eeb..7efde93224c2 100644 --- a/src/http/cookie.cr +++ b/src/http/cookie.cr @@ -156,13 +156,13 @@ module HTTP end end - def parse_cookies(header) : Array(HTTP::Cookie) + def parse_cookies(header) : Array(Cookie) cookies = [] of Cookie parse_cookies(header) { |cookie| cookies << cookie } cookies end - def parse_set_cookie(header) : HTTP::Cookie? + def parse_set_cookie(header) : Cookie? match = header.match(SetCookieString) return unless match @@ -292,7 +292,7 @@ module HTTP # ``` # request.cookies["foo"].value # => "bar" # ``` - def [](key) : HTTP::Cookie + def [](key) : Cookie @cookies[key] end @@ -306,7 +306,7 @@ module HTTP # request.cookies["foo"] = "bar" # request.cookies["foo"]?.try &.value # > "bar" # ``` - def []?(key) : HTTP::Cookie? + def []?(key) : Cookie? @cookies[key]? end @@ -325,7 +325,7 @@ module HTTP # ``` # response.cookies << HTTP::Cookie.new("foo", "bar", http_only: true) # ``` - def <<(cookie : Cookie) : HTTP::Cookie + def <<(cookie : Cookie) self[cookie.name] = cookie end @@ -337,7 +337,7 @@ module HTTP # Deletes and returns the `HTTP::Cookie` for the specified *key*, or # returns `nil` if *key* cannot be found in the collection. Note that # *key* should match the name attribute of the desired `HTTP::Cookie`. - def delete(key) : HTTP::Cookie? + def delete(key) : Cookie? @cookies.delete(key) end @@ -393,7 +393,7 @@ module HTTP end # Returns this collection as a plain `Hash`. - def to_h : Hash(String, HTTP::Cookie) + def to_h : Hash(String, Cookie) @cookies.dup end end