J'ai décidé de communiquer avec NNTP en raison de la nécessité. J'aurais pu utiliser ma propre classe NNTP que j'ai créée il y a longtemps, mais j'ai décidé d'utiliser ruby-net-nntp, qui peut utiliser Gemfile. Cette bibliothèque stocke les articles dans la classe TMail :: Mail, donc l'installation du bundle téléchargera également tmail-1.2.7.1.
J'ai résumé l'utilisation de net / nttp et les problèmes survenus dans tmail.
J'ai préparé les fichiers suivants.
source 'https://rubygems.org'
gem "ruby-net-nntp"
Téléchargez la bibliothèque à l'aide du bundler
$ bundle install --path lib
$ ls lib/ruby/2.5.0/gems/
log4r-1.1.10/ ruby-net-nntp-1.0.0/ tmail-1.2.7.1/
Lorsque j'ai essayé d'exécuter le code, j'ai immédiatement rencontré une erreur.
require "net/nntp"
Lorsque je cours, j'obtiens l'erreur suivante:
Reproduire l'erreur d'irb
$ irb
irb(main):001:0> require "rubygems"
=> false
irb(main):002:0> require "bundler/setup"
=> true
irb(main):003:0> require 'net/nntp'
Traceback (most recent call last):
14: from /usr/bin/irb:11:in `<main>'
...
2: from .../lib/ruby/2.5.0/gems/tmail-1.2.7.1/lib/tmail/utils.rb:110:in `<module:TMail>'
1: from .../lib/ruby/2.5.0/gems/tmail-1.2.7.1/lib/tmail/utils.rb:117:in `<module:TextUtils>'
RegexpError (/.../n has a non escaped non ASCII character in non ASCII-8BIT script)
Voici [http://www.ownway.info/Blog/2011/09/-invalid-multibyte-escape.html --Comment traiter le problème d'une erreur d'échappement multi-octets non valide dans l'expression régulière](http: // www. Il est expliqué dans ownway.info/Blog/2011/09/-invalid-multibyte-escape.html).
Le lien vers Google dans cet article ne fonctionne pas, donc [https://www.ruby-forum.com/t/ruby-1-9-1-invalid-multibyte-escape-regexperror/164732](https: / Vous pouvez voir la discussion originale sur /www.ruby-forum.com/t/ruby-1-9-1-invalid-multibyte-escape-regexperror/164732).
Remplacez la notation /../n où le problème se produit simplement avec Regexp.new ().
bibliothèque tmail diff
diff -ru tmail-1.2.7.1.orig/./lib/tmail/scanner_r.rb tmail-1.2.7.1/./lib/tmail/scanner_r.rb
--- tmail-1.2.7.1.orig/./lib/tmail/scanner_r.rb 2020-06-10 22:06:16.813972850 +0900
+++ tmail-1.2.7.1/./lib/tmail/scanner_r.rb 2020-06-11 11:17:51.741512220 +0900
@@ -63,24 +63,24 @@
PATTERN_TABLE = {}
PATTERN_TABLE['EUC'] =
[
- /\A(?:[#{atomchars}]+|#{iso2022str}|#{eucstr})+/n,
- /\A(?:[#{tokenchars}]+|#{iso2022str}|#{eucstr})+/n,
+ Regexp.new("\A(?:[#{atomchars}]+|#{iso2022str}|#{eucstr})+", nil, "n"),
+ Regexp.new("\A(?:[#{tokenchars}]+|#{iso2022str}|#{eucstr})+", nil, "n"),
quoted_with_iso2022,
domlit_with_iso2022,
comment_with_iso2022
]
PATTERN_TABLE['SJIS'] =
[
- /\A(?:[#{atomchars}]+|#{iso2022str}|#{sjisstr})+/n,
- /\A(?:[#{tokenchars}]+|#{iso2022str}|#{sjisstr})+/n,
+ Regexp.new("\A(?:[#{atomchars}]+|#{iso2022str}|#{sjisstr})+", nil, "n"),
+ Regexp.new("\A(?:[#{tokenchars}]+|#{iso2022str}|#{sjisstr})+", nil, "n"),
quoted_with_iso2022,
domlit_with_iso2022,
comment_with_iso2022
]
PATTERN_TABLE['UTF8'] =
[
- /\A(?:[#{atomchars}]+|#{utf8str})+/n,
- /\A(?:[#{tokenchars}]+|#{utf8str})+/n,
+ Regexp.new("\A(?:[#{atomchars}]+|#{utf8str})+", nil, "n"),
+ Regexp.new("\A(?:[#{tokenchars}]+|#{utf8str})+", nil, "n"),
quoted_without_iso2022,
domlit_without_iso2022,
comment_without_iso2022
@@ -258,4 +258,4 @@
end
end # module TMail
-#:startdoc:
\ No newline at end of file
+#:startdoc:
diff -ru tmail-1.2.7.1.orig/./lib/tmail/utils.rb tmail-1.2.7.1/./lib/tmail/utils.rb
--- tmail-1.2.7.1.orig/./lib/tmail/utils.rb 2020-06-10 22:06:16.813972850 +0900
+++ tmail-1.2.7.1/./lib/tmail/utils.rb 2020-06-11 11:11:59.582616384 +0900
@@ -114,10 +114,11 @@
lwsp = %Q| \t\r\n|
control = %Q|\x00-\x1f\x7f-\xff|
- CONTROL_CHAR = /[#{control}]/n
- ATOM_UNSAFE = /[#{Regexp.quote aspecial}#{control}#{lwsp}]/n
- PHRASE_UNSAFE = /[#{Regexp.quote aspecial}#{control}]/n
- TOKEN_UNSAFE = /[#{Regexp.quote tspecial}#{control}#{lwsp}]/n
+ ## reference: http://www.ownway.info/Blog/2011/09/-invalid-multibyte-escape.html
+ CONTROL_CHAR = Regexp.new("[#{control}]", nil, "n")
+ ATOM_UNSAFE = Regexp.new("[#{Regexp.quote aspecial}#{control}#{lwsp}]", nil, "n")
+ PHRASE_UNSAFE = Regexp.new("[#{Regexp.quote aspecial}#{control}]", nil, "n")
+ TOKEN_UNSAFE = Regexp.new("[#{Regexp.quote tspecial}#{control}#{lwsp}]", nil, "n")
# Returns true if the string supplied is free from characters not allowed as an ATOM
def atom_safe?( str )
diff -ru tmail-1.2.7.1.orig/./lib/tmail/vendor/rchardet-1.3/lib/rchardet/universaldetector.rb tmail-1.2.7.1/./lib/tmail/vendor/rchardet-1.3/lib/rchardet/universaldetector.rb
--- tmail-1.2.7.1.orig/./lib/tmail/vendor/rchardet-1.3/lib/rchardet/universaldetector.rb 2020-06-10 22:06:16.829961402 +0900
+++ tmail-1.2.7.1/./lib/tmail/vendor/rchardet-1.3/lib/rchardet/universaldetector.rb 2020-06-11 11:18:58.457912881 +0900
@@ -36,7 +36,7 @@
class UniversalDetector
attr_accessor :result
def initialize
- @_highBitDetector = /[\x80-\xFF]/
+ @_highBitDetector = Regex.new("[\x80-\xFF]")
@_escDetector = /(\033|\~\{)/
@_mEscCharSetProber = nil
@_mCharSetProbers = []
Je ne sais pas s'il existe un serveur NetNews avec un accès ouvert, mais le code pour accéder à mon INN 2.5.5 ressemble à ceci:
test.rb
#!/usr/bin/ruby
require "rubygems"
require "bundler/setup"
require 'net/nntp'
nntp = Net::NNTP.new
Net::NNTP.logger = Log4r::Logger.new("nntp")
nntp.host = "nntp.example.com"
nntp.port = 119
welcome = nntp.connect
if Net::NNTP::OKResponse === welcome
group_name = "misc.test"
group_response = nntp.process(Net::NNTP::Group.new(group_name))
listgroup_response = nntp.process(Net::NNTP::Listgroup.new(group_name))
listgroup_response.list.each { |article_id|
}
end
Cela n'a rien à voir avec Docker, je vais donc l'ajouter à la section ci-dessus. Pour l'en-tête du message stocké, certains champs ont une classe unique, mais ceux qui n'effectuent pas de traitement spécifique tel que Subject: ont leurs valeurs stockées dans la classe ** UnstructuredHeader **.
Dans ce cas, Decoder.decode est appelé, mais cette implémentation rend NKF.nkf appelé avec l'option "-mSj" (décodage MIME + encodage d'entrée Shift-JIS + encodage de sortie ISO-2022-JP). ..
Puisqu'il y a un problème si l'implémentation de Decoder.decode est corrigée, l'argument omis est utilisé et le codage de sortie est défini sur UTF8.
De plus, From: utilise la classe ** AddressHeader ** qui hérite de ** StructuredHeader **, une autre mesure est donc requise. Il existe une routine de contrôle qui suppose uniquement "jes" (ISO-2022-JP, EUC-JP, Shift-JIS) comme encodage avant d'appeler nkf, vous pouvez donc également définir un peu la classe Decoder sur ce point. Est mis en.
Différences supplémentaires avec tmail
diff -ur lib/ruby/2.5.0/gems/tmail-1.2.7.1.orig/lib/tmail/header.rb lib/ruby/2.5.0/gems/tmail-1.2.7.1/lib/tmail/header.rb
--- lib/ruby/2.5.0/gems/tmail-1.2.7.1.orig/lib/tmail/header.rb 2020-06-16 10:59:57.589086000 +0900
+++ lib/ruby/2.5.0/gems/tmail-1.2.7.1/lib/tmail/header.rb 2020-06-16 11:01:30.527304391 +0900
@@ -189,5 +189,5 @@
end
def parse
- @body = Decoder.decode(@body.gsub(/\n|\r\n|\r/, ''))
+ @body = Decoder.decode(@body.gsub(/\n|\r\n|\r/, ''), 'w')
end
def isempty?
diff -ur lib/ruby/2.7.0/gems/tmail-1.2.7.1.orig/lib/tmail/encode.rb lib/ruby/2.7.0/gems/tmail-1.2.7.1/lib/tmail/encode.rb
--- lib/ruby/2.7.0/gems/tmail-1.2.7.1.orig/lib/tmail/encode.rb 2020-06-18 14:32:37.352341212 +0900
+++ lib/ruby/2.7.0/gems/tmail-1.2.7.1/lib/tmail/encode.rb 2020-06-18 14:45:57.637057274 +0900
@@ -128,7 +128,7 @@
def initialize( dest, encoding = nil, eol = "\n" )
@f = StrategyInterface.create_dest(dest)
- @encoding = (/\A[ejs]/ === encoding) ? encoding[0,1] : nil
+ @encoding = (/\A[ejsw]/ === encoding) ? encoding[0,1] : nil
@eol = eol
end
diff -ur lib/ruby/2.7.0/gems/tmail-1.2.7.1.orig/lib/tmail/header.rb lib/ruby/2.7.0/gems/tmail-1.2.7.1/lib/tmail/header.rb
--- lib/ruby/2.7.0/gems/tmail-1.2.7.1.orig/lib/tmail/header.rb 2020-06-18 14:32:37.993666420 +0900
+++ lib/ruby/2.7.0/gems/tmail-1.2.7.1/lib/tmail/header.rb 2020-06-18 14:47:16.026796369 +0900
@@ -147,7 +147,7 @@
def body
ensure_parsed
- v = Decoder.new(s = '')
+ v = Decoder.new(s = '', "w")
do_accept v
v.terminate
s
@@ -225,7 +225,7 @@
rescue SyntaxError
if not save and mime_encoded? @body
save = @body
- @body = Decoder.decode(save)
+ @body = Decoder.decode(save, "w")
retry
elsif save
@body = save
Lors de l'application d'un correctif dans un environnement ruby-2.7 tel que Ruby de Docker: image 2.7-alpine ou Ubuntu 20.04 LTS, convertissez le fichier "2.5.0" en "2.7.0" avant de l'utiliser.
2.7 Exemple d'application de patch à l'environnement
$ sed -e 's/2.5.0/2.7.0/g' tmail.diff | patch -p0
L'image Docker utilise ruby: 2.7-alpine. Il y avait des erreurs, dont certaines n'étaient pas apparentes dans ruby-2.5, et dont certaines venaient d'essayer de s'exécuter en tant qu'utilisateur non root.
Le Dockerfile sans build multi-étapes, etc. est affiché ci-dessous pour le moment. Dans le répertoire actuel, il y a un code de modèle ruby-sinatra créé par openapi-generator tel que Gemfile et config.ru.
Dockerfile
FROM ruby:2.7-alpine as rubydev
RUN apk --no-cache add tzdata bash ca-certificates make gcc libc-dev linux-headers build-base patch
RUN mkdir /app
COPY . /app
WORKDIR /app
RUN cp /usr/local/include/ruby-2.7.0/ruby/defines.h /usr/local/include/ruby-2.7.0/defines.h
RUN bundle config path lib
RUN bundle install
ENV SINATRA_PORT 8080
EXPOSE $SINATRA_PORT
ADD run.sh /run.sh
RUN chmod +x /run.sh
RUN addgroup sinatra
RUN adduser -S -G sinatra sinatra
# RUN cp -r /root/.bundle /home/sinatra/.bundle
USER sinatra
ENTRYPOINT ["/run.sh"]
Une erreur se produira si define.h ne peut pas être compilé.
Erreur rencontrée
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
...
current directory: /app/lib/ruby/2.7.0/gems/tmail-1.2.7.1/ext/tmailscanner/tmail
make "DESTDIR="
make: *** No rule to make target '/usr/local/include/ruby-2.7.0/defines.h',
needed by 'tmailscanner.o'. Stop.
...
Puisque define.h n'existe pas à l'emplacement attendu, il a été pris en charge par cp.
Solution de contournement ajoutée à Dockerfile
RUN cp /usr/local/include/ruby-2.7.0/ruby/defines.h \
/usr/local/include/ruby-2.7.0/defines.h
Dans l'environnement d'Ubuntu 18.04 + ruby-2.5 (paquet deb), ruby / define.h a été explicitement spécifié à la fin de Makefile, mais pour autant que j'ai vérifié Makefile de tmail dans Dockerfile, -I flag Il semble que seul /usr/local/include/ruby-2.7.0 était spécifié dans.
ubuntu+ruby-2.5 environnements
tmailscanner.o: tmailscanner.c $(hdrdir)/ruby/ruby.h $(arch_hdrdir)/ruby/config.h $(hdrdir)/ruby/defines.h Makefile
Dans l'environnement 2.7-alpin, pour une raison quelconque, define.h devrait être ruby / define.h.
2.7-image de docker alpin
tmailscanner.o: tmailscanner.c $(hdrdir)/ruby.h $(arch_hdrdir)/ruby/config.h $(hdrdir)/defines.h Makefile
Le problème est mkmf.rb, dans le prétraitement pour écrire le fichier depend, le processus pour modifier la ligne qui est $ (hdrdir) /defines.h en $ (hdrdir) ruby / définit.h est ruby-2.7 mkmf. C'était parce qu'il a été supprimé dans rb.
mkmf.rb
## ruby-2.5 mkmf.rb
depend.each_line do |line|
line.gsub!(/\.o\b/, ".#{$OBJEXT}")
line.gsub!(/\{\$\(VPATH\)\}/, "") unless $nmake
line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h)
line.gsub!(%r"\$\(hdrdir\)/(?!ruby(?![^:;/\s]))(?=[-\w]+\.h)", '\&ruby/')
if $nmake && /\A\s*\$\(RM|COPY\)/ =~ line
## ruby-2.7 mkmf.rb
depend.each_line do |line|
line.gsub!(/\.o\b/, ".#{$OBJEXT}")
line.gsub!(/\{\$\(VPATH\)\}/, "") unless $nmake
line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h)
if $nmake && /\A\s*\$\(RM|COPY\)/
Cela ressemble à la modification validée sur https://github.com/ruby/ruby/commit/3d1c86a26f0c96a9c1d0247b968aa96e6f3c30bb#diff-7aa560cb6196deeb96779cd175e8e589.
Il semble que je voulais corriger l'emplacement de ruby.h, mais probablement au lieu de supprimer la ligne correspondante, j'ai ajouté une ligne gsub! En dessous qui réécrit "ruby / ruby.h" en "ruby.h" Je pense que j'aurais dû le faire.
Il est enregistré sous le nom https://bugs.ruby-lang.org/issues/16490 dans le système de suivi des problèmes de Ruby, mais il semble que l'examen ne progresse pas.
Lorsque vous l'utilisez avec Docker, il n'y a pas d'autre moyen que de prendre une solution de contournement correspondante en modifiant l'emplacement de define.h plutôt que de patcher mkmf.rb ...
Dans ruby-2.5, j'ai utilisé
$ bundle install --path lib, mais j'ai reçu un avertissement disant obsolète, donc je l'ai changé pour utiliser `` `` $ bundle config path lib
Faire.
Pour cette raison, cela dépend du contenu du fichier ~ / .bundle / config, j'ai donc changé l'utilisateur au moment de l'exécution avec USER sinatra
, donc j'ai rencontré une erreur car le fichier ~ / .bundle / config n'existe pas. fait.
Détails de l'erreur
$ make docker-run
sudo docker run -it --rm -p 8080:8080 --name nntp-reader nntp-reader:latest
bundler: command not found: rackup
Install missing gem executables with `bundle install`
Makefile:43: recipe for target 'docker-run' failed
make: *** [docker-run] Error 127
Les mesures suivantes peuvent être envisagées en premier.
Solution de contournement 1-run.Résoudre lors de l'exécution avec sh
#!/bin/bash
bundle config path lib ##Solution de contournement ajoutée
export SINATRA_PORT=${SINATRA_PORT:-8080}
bundle exec rackup --host 0.0.0.0 --port $SINATRA_PORT
La méthode suivante a été adoptée cette fois.
Solution de contournement 2-Résoudre lors de la création d'une image avec Dockerfile
RUN cp -r /root/.bundle /home/sinatra/.bundle
c'est tout
Recommended Posts