mirror of
				https://gitea.invidious.io/iv-org/invidious
				synced 2025-06-05 23:29:12 +02:00 
			
		
		
		
	Fix crystal overrides (#2295)
* Move Crystal stdlib classes overrides to a separate file * Document known crystal overrides * Update crystal overrides for HTTP::Client socket * Update shard.yml to restrict crystal versions * Fix compilation error in Crystal 1.1.x (See https://github.com/crystal-lang/crystal/issues/10965 for more details about this issue).
This commit is contained in:
		| @@ -26,6 +26,6 @@ dependencies: | |||||||
|     github: iv-org/lsquic.cr |     github: iv-org/lsquic.cr | ||||||
|     version: ~> 2.18.1-2 |     version: ~> 2.18.1-2 | ||||||
|  |  | ||||||
| crystal: 1.0.0 | crystal: ">= 1.0.0, < 2.0.0" | ||||||
|  |  | ||||||
| license: AGPLv3 | license: AGPLv3 | ||||||
|   | |||||||
							
								
								
									
										70
									
								
								src/invidious/helpers/crystal_class_overrides.cr
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/invidious/helpers/crystal_class_overrides.cr
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | |||||||
|  | # Override of the TCPSocket and HTTP::Client classes in oder to allow an | ||||||
|  | # IP family to be selected for domains that resolve to both IPv4 and | ||||||
|  | # IPv6 addresses. | ||||||
|  | # | ||||||
|  | class TCPSocket | ||||||
|  |   def initialize(host : String, port, dns_timeout = nil, connect_timeout = nil, family = Socket::Family::UNSPEC) | ||||||
|  |     Addrinfo.tcp(host, port, timeout: dns_timeout, family: family) do |addrinfo| | ||||||
|  |       super(addrinfo.family, addrinfo.type, addrinfo.protocol) | ||||||
|  |       connect(addrinfo, timeout: connect_timeout) do |error| | ||||||
|  |         close | ||||||
|  |         error | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # :ditto: | ||||||
|  | class HTTP::Client | ||||||
|  |   property family : Socket::Family = Socket::Family::UNSPEC | ||||||
|  |  | ||||||
|  |   private def io | ||||||
|  |     io = @io | ||||||
|  |     return io if io | ||||||
|  |     unless @reconnect | ||||||
|  |       raise "This HTTP::Client cannot be reconnected" | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     hostname = @host.starts_with?('[') && @host.ends_with?(']') ? @host[1..-2] : @host | ||||||
|  |     io = TCPSocket.new hostname, @port, @dns_timeout, @connect_timeout, @family | ||||||
|  |     io.read_timeout = @read_timeout if @read_timeout | ||||||
|  |     io.write_timeout = @write_timeout if @write_timeout | ||||||
|  |     io.sync = false | ||||||
|  |  | ||||||
|  |     {% if !flag?(:without_openssl) %} | ||||||
|  |       if tls = @tls | ||||||
|  |         tcp_socket = io | ||||||
|  |         begin | ||||||
|  |           io = OpenSSL::SSL::Socket::Client.new(tcp_socket, context: tls, sync_close: true, hostname: @host) | ||||||
|  |         rescue exc | ||||||
|  |           # don't leak the TCP socket when the SSL connection failed | ||||||
|  |           tcp_socket.close | ||||||
|  |           raise exc | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |     {% end %} | ||||||
|  |  | ||||||
|  |     @io = io | ||||||
|  |   end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # Mute the ClientError exception raised when a connection is flushed. | ||||||
|  | # This happends when the connection is unexpectedly closed by the client. | ||||||
|  | # | ||||||
|  | class HTTP::Server::Response | ||||||
|  |   class Output | ||||||
|  |     private def unbuffered_flush | ||||||
|  |       @io.flush | ||||||
|  |     rescue ex : IO::Error | ||||||
|  |       unbuffered_close | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | # TODO: Document this override | ||||||
|  | # | ||||||
|  | class PG::ResultSet | ||||||
|  |   def field(index = @column_index) | ||||||
|  |     @fields.not_nil![index] | ||||||
|  |   end | ||||||
|  | end | ||||||
| @@ -509,12 +509,6 @@ def check_table(db, table_name, struct_type = nil) | |||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
| class PG::ResultSet |  | ||||||
|   def field(index = @column_index) |  | ||||||
|     @fields.not_nil![index] |  | ||||||
|   end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| def get_column_array(db, table_name) | def get_column_array(db, table_name) | ||||||
|   column_array = [] of String |   column_array = [] of String | ||||||
|   db.query("SELECT * FROM #{table_name} LIMIT 0") do |rs| |   db.query("SELECT * FROM #{table_name} LIMIT 0") do |rs| | ||||||
| @@ -699,47 +693,3 @@ def proxy_file(response, env) | |||||||
|     IO.copy response.body_io, env.response |     IO.copy response.body_io, env.response | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
| class HTTP::Server::Response |  | ||||||
|   class Output |  | ||||||
|     private def unbuffered_flush |  | ||||||
|       @io.flush |  | ||||||
|     rescue ex : IO::Error |  | ||||||
|       unbuffered_close |  | ||||||
|     end |  | ||||||
|   end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| class HTTP::Client |  | ||||||
|   property family : Socket::Family = Socket::Family::UNSPEC |  | ||||||
|  |  | ||||||
|   private def socket |  | ||||||
|     socket = @socket |  | ||||||
|     return socket if socket |  | ||||||
|  |  | ||||||
|     hostname = @host.starts_with?('[') && @host.ends_with?(']') ? @host[1..-2] : @host |  | ||||||
|     socket = TCPSocket.new hostname, @port, @dns_timeout, @connect_timeout, @family |  | ||||||
|     socket.read_timeout = @read_timeout if @read_timeout |  | ||||||
|     socket.sync = false |  | ||||||
|  |  | ||||||
|     {% if !flag?(:without_openssl) %} |  | ||||||
|       if tls = @tls |  | ||||||
|         socket = OpenSSL::SSL::Socket::Client.new(socket, context: tls, sync_close: true, hostname: @host) |  | ||||||
|       end |  | ||||||
|     {% end %} |  | ||||||
|  |  | ||||||
|     @socket = socket |  | ||||||
|   end |  | ||||||
| end |  | ||||||
|  |  | ||||||
| class TCPSocket |  | ||||||
|   def initialize(host, port, dns_timeout = nil, connect_timeout = nil, family = Socket::Family::UNSPEC) |  | ||||||
|     Addrinfo.tcp(host, port, timeout: dns_timeout, family: family) do |addrinfo| |  | ||||||
|       super(addrinfo.family, addrinfo.type, addrinfo.protocol) |  | ||||||
|       connect(addrinfo, timeout: connect_timeout) do |error| |  | ||||||
|         close |  | ||||||
|         error |  | ||||||
|       end |  | ||||||
|     end |  | ||||||
|   end |  | ||||||
| end |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user