Changesets can be listed by changeset number.
The Git repository is here.
Changeset 434
Fix breakage of graphical revisions by character set conversion of
all data from the CVS viewer script; just parse text/* types.
Switch from forced HTTP fetching of related resources to forced
HTTPS fetching, with certificate chain support.
- Comitted by: rool
- Date: Friday August 30 03:16:00 2013 (over 11 years ago)
Affected files:
- rool/rails/rcvsweb/trunk/app/controllers/application.rb (diff)
- rool/rails/rcvsweb/trunk/app/controllers/revisions_controller.rb (diff)
- rool/rails/rcvsweb/trunk/config/environment.rb (diff)
- rool/rails/rcvsweb/trunk/lib/revision_parser.rb (diff)
rool/rails/rcvsweb/trunk/app/controllers/application.rb:
prev. | current | |
def capture_script_output(script_location, extra_prefix) | ||
# Get the request URI in a way that works for FCGI and regular | ||
45 | | |
45 | # CGI, at least for LigHTTPd. Strip off the root path prefix | |
# (location of the Rails application) if present. | ||
uri = @request.env['REQUEST_URI'].dup # NOT a full URI | ||
... | ... | |
# to UTF-8 in passing. | ||
command += "#{script_location}" | ||
105 | | |
105 | data = `#{command}` | |
106 | ||
107 | # I searched for nearly two hours through endless documentation about | |
108 | # a ridiculous number of classes and methods related to HTTP, but not | |
109 | # one single thing just took a string and parsed it as an HTTP response, | |
110 | # or even just parsed HTTP headers. | |
111 | # | |
112 | # There may be a way but I gave up in the face of poor documentation and | |
113 | # an excess of often obtuse different ways of doing the same thing over | |
114 | # and over, with nothing providing the simple function I wanted. There's | |
115 | # a gem that does it, but I don't want extra dependencies - all the HTTP | |
116 | # header parsing code is all there, it's just locked away behind a | |
117 | # labyrinth of similar named classes and dodgy APIs. | |
118 | # | |
119 | # All I want is the content type, but reliably! | |
120 | # | |
121 | # Thus, unreliable hack is forced. | |
122 | ||
123 | headers = data.split("\r\n\r\n", 2).first || '' | |
124 | headers = headers.downcase.split("\r\n") || [] # Don't care about multiline headers here | |
125 | parsed = {} | |
126 | ||
127 | headers.each do | header | | |
128 | (key, value) = header.split(':', 2) | |
129 | parsed[key] = value.strip | |
130 | end | |
131 | ||
132 | type = parsed['content-type'] | |
133 | ||
134 | if ( ! type.nil? && type[0..4] == 'text/' ) | |
135 | return Iconv.conv("UTF8", "ISO-8859-1", data) | |
136 | else | |
137 | return data | |
138 | end | |
end | ||
# Parse script output - pass the raw output data from the script and a |
rool/rails/rcvsweb/trunk/app/controllers/revisions_controller.rb:
prev. | current | |
render :file => "#{CVSLOG2WEB_OUTPUT}/recent.html", :layout => 'default' | ||
end | ||
10 | | |
10 | ||
def logs | ||
# Use cvslog2web output directly for log details of a specific change. | ||
# Links are based off an 'ident' parameter pulled in via a query string; | ||
... | ... | |
render :file => "#{CVSLOG2WEB_OUTPUT}/#{log}.html", :layout => 'default' | ||
end | ||
23 | | |
23 | ||
def revisions | ||
# Create a revision parser for a CVSHistory RSS feed. Get a | ||
# hash keyed by revision number (as a string), each entry | ||
... | ... | |
render :layout => 'default' | ||
end | ||
90 | | |
90 | ||
# Synthesised revisions: return the CVS History feed URL. | ||
92 | | |
92 | ||
def get_parser_url | ||
# For sites that hold a development service on usual port numbers, | ||
96 | | |
97 | | |
98 | | |
99 | | |
100 | | |
96 | # check to see if we're using the development HTTP port. If so, | |
97 | # change to the development HTTPS port. Then check to see if we're | |
98 | # on the development HTTPS port; if not, change to port 443 for a | |
99 | # regular HTTPS service. | |
100 | ||
port = request.env['SERVER_PORT'] | ||
102 | | |
103 | | |
104 | | |
105 | | |
102 | port = DEVEL_HTTPS_PORT if (port == DEVEL_HTTP_PORT) | |
103 | port = 443 if (port != DEVEL_HTTPS_PORT) | |
104 | ||
105 | "https://#{request.host}:#{port}#{CVSLOG2WEB_PREFIX}" + | |
'?revsel1=na&revsel2=na&datesel1=na&datesel2=na&selop=in&opA=on&opM=on&opR=on&opT=on&limit=1&rss=1' | ||
107 | | |
107 | end | |
end |
rool/rails/rcvsweb/trunk/config/environment.rb:
prev. | current | |
# path to use for URLs for CVShistory - the bit up to and including | ||
# the ".cgi", before the query string is appended, excluding the | ||
# host. The host is taken from ENV['SERVER_ADDR']. If the request | ||
21 | ||
22 | ||
23 | ||
24 | ||
21 | # uses port DEVEL_HTTP_PORT, it is switched to DEVEL_HTTPS_PORT for | |
22 | # an HTTPS request. If the port is already DEVEL_HTTPS_PORT it | |
23 | # is left alone, again for an HTTPS request. Otherwise, the port | |
24 | # is reset to 443. | |
25 | # | |
26 | # Since HTTPS requests may require a certificate chain, you can | |
27 | # configure this in SSL_CERT_CHAIN; this should point to a ".crt" | |
28 | # bundle (as a full path) giving the chain of trust for your SSL | |
29 | # certificate at the target site. You may choose to provide this | |
30 | # via an environment variable if you wish. Use 'nil' or an empty | |
31 | # string if you want no such chain specifying. | |
PATH_PREFIX = '/viewer' | ||
CVSWEB_LOCATION = '/home/rool/devel/perl/cvsweb/cvsweb.cgi' | ||
... | ... | |
CVSLOG2WEB_PREFIX = '/python/cvshistory/cvshistory.cgi' | ||
DEVEL_HTTP_PORT = '25080' | ||
DEVEL_HTTPS_PORT = '25081' | ||
40 | SSL_CERT_CHAIN = ENV[ 'SSL_CERT_CHAIN' ] | |
Rails::Initializer.run do |config| | ||
# Skip frameworks that are not used. |
rool/rails/rcvsweb/trunk/lib/revision_parser.rb:
prev. | current | |
require 'strscan' | ||
2 | require 'uri' | |
3 | require 'net/https' | |
require 'rss' | ||
class RevisionDetails | ||
... | ... | |
# | ||
def fetch_and_parse(extract_logs = false) | ||
70 | # Site-specific issue: At ROOL, the SSL certificate issuer uses | |
71 | # a certificate chain which isn't known about by Ruby initially. | |
72 | # This causes SLL failures if we were to just try and get the | |
73 | # RSS parser to fetch & parse the data by passing it "@feed" in | |
74 | # "RSS::Parser.parse()". Instead we have to manually do the SSL | |
75 | # foot work and pass the parser the fetched data. | |
76 | ||
77 | uri = URI.parse( @feed ) | |
78 | https = Net::HTTP.new( uri.host, uri.port ) | |
79 | https.use_ssl = true | |
80 | https.verify_mode = OpenSSL::SSL::VERIFY_PEER | |
81 | https.ca_file = SSL_CERT_CHAIN unless ( SSL_CERT_CHAIN.nil? || SSL_CERT_CHAIN.empty? ) | |
82 | ||
83 | feed_data = https.start do | http | | |
84 | request = Net::HTTP::Get.new( uri.request_uri ) | |
85 | response = https.request( request ) | |
86 | ||
87 | raise "#{ response.code }: #{ response.messages }" unless ( response.code.to_i >= 200 && response.code.to_i <= 299 ) | |
88 | ||
89 | response.body | |
90 | end | |
91 | ||
revisions = {} | ||
69 | | |
93 | rss = RSS::Parser.parse( feed_data ) | |
rss.items.each do |item| | ||
# Description format: |