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 | ||||
|     version: ~> 2.18.1-2 | ||||
|  | ||||
| crystal: 1.0.0 | ||||
| crystal: ">= 1.0.0, < 2.0.0" | ||||
|  | ||||
| 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 | ||||
|  | ||||
| class PG::ResultSet | ||||
|   def field(index = @column_index) | ||||
|     @fields.not_nil![index] | ||||
|   end | ||||
| end | ||||
|  | ||||
| def get_column_array(db, table_name) | ||||
|   column_array = [] of String | ||||
|   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 | ||||
|   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