Symfoware

Symfowareについての考察blog

IIS 10とTomcat 8.5をApplication Request Routingで連携

昔は
Webサーバー:IIS
アプリケーションサーバー:Tomcat
の構成を取るとき、mod_jkを使用していたかと思います。

最近は、ルーティングを行うIIS拡張が用意されているようで、こちらを使用すれば
狙った動作が行えるようです。
Application Request Routingを使ってみた

早速試してみます。


IIS



こちらの手順でインストールしたWindows Server 2016 + IIS 10.0の環境でテストしました。
Windows Server 2016 にIIS 10.0をインストールし、ASP.NETを有効化




Application Request Routing



こちらからインストーラーをダウンロードしました。
Application Request Routing

811_01.png


「ARRv3_0.exe」が取得できますので、実行します。
「インストール」をクリックしてインストールを実行。

811_02.png


ライセンスの確認です。
「同意する」をクリックするとインストールが開始されます。

811_03.png


インストール終了。「完了」をクリックします。

811_04.png


「終了」でインストーラーを終了します。

811_05.png


インストール後、IISマネージャーの画面を見ると、
・Application Request Routing
・URL書き換え
の機能が追加されています。

811_06.png




ルーティング



こちらで作成したサーブレットにルーティングしてみます。
Eclipse TomcatPluginでサーブレットアプリケーションの作成

ちょっとプログラムを修正しました。


  1. package sample;
  2. import java.io.IOException;
  3. import java.io.PrintWriter;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.annotation.WebServlet;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. @WebServlet("/SampleServlet")
  10. public class MyServlet extends HttpServlet {
  11.     private static final long serialVersionUID = 1L;
  12.     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13.         // 要求文字コードのセット
  14.         request.setCharacterEncoding("UTF-8");
  15.         // 応答文字コードのセット
  16.         response.setContentType("text/html; charset=UTF-8");
  17.         // 出力ストリームの取得
  18.         PrintWriter out = response.getWriter();
  19.         // クライアント(ブラウザ)への出力
  20.         out.println("<html lang=\"ja\">");
  21.         out.println("<head><title>Servletテンプレート</title>");
  22.         out.println("</head><body>");
  23.         out.println("<h1>Servletのテンプレートです。</h1>");
  24.         out.println("<img src=\"img/banar.png\">");
  25.         out.println("");
  26.         out.println("</body></html>");
  27.         // 出力ストリームを閉じる
  28.         out.close();
  29.     }
  30. }




今後のテスト用にimg/banar.pngを表示するように修正しています。

811_07.png


※バナーの作成はこちらのサイトを利用させていただきました。
進撃の巨人ロゴジェネレーター




IISの設定画面から「Application Request Routing」を選択。

811_08.png


右側「Proxy」の項目にある「Server Proxy Settings...」をクリック。

811_09.png


先頭の「Enable proxy」にチェックをつけて有効にします。

811_10.png


画面をスクロールして一番下「Proxy Type」の設定です。
「Use URL Rewrite to inspectioncoming requests」にチェック。
今回SSLは使用しないので、「Enable SSL offloading」のチェックは外しました。

「Reverse proxy」の項目に、サーブレットが動いているサーバーのIPとポートを入力します。
※今回は「192.168.1.4:8080」

入力が終わったら「適用」をクリックして内容を反映させます。

811_11.png


「URL書き換え」の項目を開きます。

811_12.png


新しくルールが追加されました。

811_13.png


内容を見てみると、http://192.168.1.4:8080/[パラメーター]に書き換えられることが確認できます。

811_14.png


IISが動いているサーバーは「192.168.1.102」です。
http://192.168.1.102/sample/SampleServletにアクセスすると、ちゃんとサーブレットが実行されました。

811_15.png






除外設定



画像はIISから配信するよう構成します。
c:\inetpub\wwwroot\sample\imgにbanar.pngという名前でこの画像を配置しました。

811_16.png


「URL書き換え」の画面を表示し、「規則の追加」をクリックします。

811_17.png


表示されるダイアログで「空の規則」を選択し、「OK」をクリック。

811_18.png


ルールの名前は適当に「画像配信」としました。
要求されたURLでは「パターンに一致する」を選択。

パターンは正規表現で指定できます。
今回は「img」ディレクトリへのアクセスはIISで配信するよう構成してみようと思います。
パターンに「.*/img/.*」と入力しました。/img/が含まれているURLはIISで処理します。

811_19.png


画面をスクロールして最下部。
アクションの種類は「なし」
「後続の規則の処理を停止する」にチェックをつけておきます。

811_20.png


新規作成したルールは末尾に追加されます。
サーブレットへproxyする前に処理しないとTomcat側の画像が表示されてしまうので、
右下「上に移動」をクリックして最初にルールが適用されるよう変更しておきます。

811_21.png

811_22.png


ブラウザを更新してやると、ちゃんとIISに配置したバナー画像が表示されました。

811_23.png




【参考URL】

Application Request Routingを使ってみた

テーマ:サーバ - ジャンル:コンピュータ

  1. 2017/11/19(日) 16:02:14|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Redmine 3系 チケットやWikiの記述にHTMLタグを使用したい(redcloth3.rb)

Redmine 3.4.3をインストールしました。
Redmine 3.4.3をUbuntu Server 16.04へインストール(PostgreSQL, rbenv使用)

チケットやwikiにaタグを記載すると

810_01.png

エスケープされてしまいます。

810_02.png

ここはリンクになってほしい。



lib/redcloth3.rb



Wikiの記述にHTMLタグを使用したい

lib/redcloth3.rbを編集すればよいとのことですが、そんなファイルないよ...

探しまわった結果、パスが変わっています。


lib/redmine/wiki_formatting/textile/redcloth3.rb




Redmine 3系からでしょうか?
変更となったバージョンは調べてませんが、このファイルを編集してやります。
Redmineは/opt/redmine-3.4.3にインストールしています。


$ vi /opt/redmine-3.4.3/lib/redmine/wiki_formatting/textile/redcloth3.rb




ファイルの末尾、1214行目付近に「ALLOWED_TAGS」の項目があります。


  1. ALLOWED_TAGS = %w(redpre pre code kbd notextile)



参考にしたサイトに従い、aとfontを追記してみます。


  1. ALLOWED_TAGS = %w(redpre pre code kbd notextile a font)




編集がおわったらRedmineを再起動。
再度チケットの画面を見てみると、無事エスケープされずリンクになっていました。

810_03.png


テーマ:サーバ - ジャンル:コンピュータ

  1. 2017/11/18(土) 19:08:48|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Redmine 3.4.3をUbuntu Server 16.04へインストール(PostgreSQL, rbenv使用)

Ubuntu Server 16.04へRedmine 3.4.3をインストールしてみます。

こちらを参考にしました。
Redmine 3.0.0をDebian 7(Wheezy)にインストールする



Rubyのインストール



rbenvを使用しました。
Ubuntu 16.04にrbenvでRubyのバージョンを管理する

Rubyのバージョンは2.4.2です。


$ ruby --version
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]






PostgreSQLのインストール



データベースはPostgreSQL 10.1を使用します。
PostgreSQL 10.1をUbuntu 16.04へインストールし、外部からの接続を許可




Redmineのインストール



gemでbundlerをインストール。


$ gem install bundler --no-rdoc --no-ri




Redmineのソースコードを取得し展開します。


$ cd /opt
$ sudo wget http://www.redmine.org/releases/redmine-3.4.3.tar.gz
$ sudo tar xzf redmine-3.4.3.tar.gz




PostgreSQL接続ドライバのビルド時にヘッダーが必要なので、事前にインストールしておきます。
合わせて、Redmineで使用するライブラリのビルド時に必要となるimagemagickをインストールしておきます。


$ sudo apt install postgresql-server-dev-10
$ sudo apt install imagemagick libmagickcore-dev libmagickwand-dev




/opt/redmine-3.4.3でbundle installコマンドを実行します。
これでRedmineが依存しているライブラリがインストールされます。
--withoutで使わないmysqlやsqliteをインストールしないようにしておきました。
※このオプション、もう過去のものかも。


$ cd /opt/redmine-3.4.3
$ bundle install --without development test mysql sqlite






データベースの作成



PostgreSQLに「redmine」というデータベースを作成します。
ユーザーの「pgadmin」は事前に作成しておきました。


$ psql -h localhost -U pgadmin -d postgres
Password for user pgadmin:
psql (10.1)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=# create database redmine;
CREATE DATABASE
postgres=# \q




config/database.ymlを新規作成。


$ vi config/database.yml




データベースの接続情報を記載します。


production:
  adapter: postgresql
  database: redmine
  host: localhost
  username: pgadmin
  password: "P@ssw0rd"




rakeコマンドでデータベースの初期化を行います。


$ rake generate_secret_token
Could not find gem 'pg (~> 0.18.1)' in any of the gem sources listed in your Gemfile.
Run `bundle install` to install missing gems.




エラーになりました。

どうやら、bundle install実行時にdatabase.ymlに記載されているadapterを読み取り、
適したドライバをインストールしているようです。

database.ymlは作成したので、再度bundle installを実行。


$ bundle install --without development test mysql sqlite
...
Fetching pg 0.18.4
Installing pg 0.18.4 with native extensions
...




PostgreSQLへの接続ライブラリがインストールされました。
再度データベースの初期化を実行。


$ rake generate_secret_token
$ RAILS_ENV=production rake db:migrate




デフォルトの日本語データを設定。


$ RAILS_ENV=production rake redmine:load_default_data

Select language: ar, az, bg, bs, ca, cs, da, de, el, en, en-GB, es, es-PA,
et, eu, fa, fi, fr, gl, he, hr, hu, id, it, ja, ko, lt, lv, mk, mn, nl, no,
pl, pt, pt-BR, ro, ru, sk, sl, sq, sr, sr-YU, sv, th, tr, uk, vi, zh, zh-TW [en] ja




webrickで動作確認します。


$ ruby bin/rails server webrick -e production -b 0.0.0.0




http://[サーバーIP]:3000を表示すればログイン画面が表示されます。
初期ID、パスワードは共に「admin」
※ログインすると最初にパスワードの変更を求められました。

[管理] - [情報]を確認します。

809_01.png


Redmine version:3.4.3.stable
Ruby version:2.4.2-p198 (2017-09-14) [x86_64-linux]
Rails version:4.2.8



Ruby 2.4.2 + Redmine 3.4.3が動いています。


webサーバーでの動作はこちらが参考になると思います。

Apache + passenger
Redmine 2.3.1をDebian 7(Wheezy)にインストールする

nginx + Puma
Puma + nginxでRedmine 2.6を動かす

nginx + jungle
jungleを使用して、Pumaをデーモンで自動起動する

テーマ:サーバ - ジャンル:コンピュータ

  1. 2017/11/18(土) 18:48:03|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Ubuntu 16.04にrbenvでRubyのバージョンを管理する

今までRVMを使用していたのですが、rbenvも使ってみようと思います。

こちらを参考にさせていただきました。
Ubuntu14.04 に rbenv をインストールして Ruby のバージョン管理



rbenvのインストール



まず、インストール済のバッケージを最新に更新しておきます。


$ sudo apt update
$ sudo apt upgrade




rubyのビルドに必要なパッケージをインストール。


$ sudo apt install git build-essential libssl-dev



rbenvを取得


$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build




.profileを編集。


$ vi ~/.profile




末尾に以下の内容を追記。


export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"




追記した内容を反映。


$ source ~/.profile




ちゃんとコマンドを認識していますね。


$ rbenv --version
rbenv 1.1.1-6-g2d7cefe







Rubyのインストール



インストール可能なバージョンの一覧を表示してみます。


$ rbenv install --list




現時点では、2.4.2が最新のようです。
バージョンを指定してインストールしてみます。


$ rbenv install 2.4.2
Downloading ruby-2.4.2.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.2.tar.bz2
Installing ruby-2.4.2...

BUILD FAILED (Ubuntu 16.04 using ruby-build 20170914-15-g449ba6b)

Inspect or clean up the working tree at /tmp/ruby-build.20171118173115.12067
Results logged to /tmp/ruby-build.20171118173115.12067.log

Last 10 log lines:
installing rdoc:             /home/baranche/.rbenv/versions/2.4.2/share/ri/2.4.0/system
installing capi-docs:         /home/baranche/.rbenv/versions/2.4.2/share/doc/ruby
The Ruby readline extension was not compiled.
ERROR: Ruby install aborted due to missing extensions
Try running `apt-get install -y libreadline-dev` to fetch missing dependencies.

Configure options used:
--prefix=/home/baranche/.rbenv/versions/2.4.2
LDFLAGS=-L/home/baranche/.rbenv/versions/2.4.2/lib
CPPFLAGS=-I/home/baranche/.rbenv/versions/2.4.2/include




エラーになりました。
警告通りlibreadline-devをインストールしてリトライ。


$ sudo apt install libreadline-dev
$ rbenv install 2.4.2
Downloading ruby-2.4.2.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.2.tar.bz2
Installing ruby-2.4.2...
Installed ruby-2.4.2 to /home/baranche/.rbenv/versions/2.4.2




インストール成功です。
しかし、この状態でrubyコマンドを実行してもエラーになります。


$ ruby --version
rbenv: ruby: command not found

The `ruby' command exists in these Ruby versions:
2.4.2





「rbenv global」で使用するrubyのバージョンを指定してやります。


$ rbenv global 2.4.2




これでrubyコマンドが認識されました。


$ ruby --version
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]


テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/11/18(土) 17:46:18|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

IIS 10.0 + C#で自作したHTTPハンドラー(IHttpHandle)を動作させる

IISで動くアプリケーションで、特定のURLの時に処理を実行したい。
(ログの出力や認証チェック等)

Java Servletだとフィルターで実装する処理でしょうか。


調べてみると、HttpModuleやHttpHandleをC#で作成すれば願いが叶いそうです。
今回は独自のHTTPハンドラーをC#で作成。
IISに設定してみます。



IIS 10.0のインストール



Windows Server 2016で試してみます。
IISのインストールは以前行っているのでこちらを参考にします。
Windows Server 2016 にIIS 10.0をインストールし、ASP.NETを有効化


インストール時のポイントですが、
「ASP.NET 4.6を必ず有効にすること」

ASP.NETやISAPI拡張がインストールされていないと、ハンドラーを設定した時、


このハンドラーに対して指定されたモジュールが、モジュールの一覧にありません。
スクリプト マップ ハンドラー マッピングを追加する場合は、
モジュール一覧にIsapiModule または CgiModule が存在している必要があります。




1. 500.19 エラー
HTTP エラー 500.19 - Internal Server Error
ページに関連する構成データが無効であるため、要求されたページにアクセスできません。
エラー コード 0x80070021
構成エラー この構成セクションをこのパスで使用できません。
この問題は、親レベルでセクションがロックされているときに発生します。
ロック状態は既定で設定されているか (overrideModeDefault="Deny")、または overrideMode="Deny"
もしくは従来の allowOverride="false" を含んだ場所タグによって明示的に設定されます。




こういったエラーが表示され動いてくれません。
ハマりました。


インストール時に忘れず「ASP.NET 4.6」を追加しておきます。

804_01.png





サンプルプログラム



こちらのチュートリアル
同期 HTTP ハンドラーの作成
そして、こちらのサイトを参考にしました。
.NETでコントローラを作ってみる


アクセスすると「Hello World」と表示するハンドラーを作成してみます。

・Sample.cs


  1. using System.Web;
  2. namespace Sample {
  3.     
  4.     public class MyHandler : System.Web.IHttpHandler {
  5.         
  6.         public bool IsReusable {
  7.             get { return false; }
  8.         }
  9.         
  10.         public void ProcessRequest(HttpContext context) {
  11.             context.Response.ContentType = "text/html";
  12.             context.Response.Write("Hello World");
  13.         }
  14.     }
  15. }




IsReusableが、インスタンスを使いまわしてよいか(だと思う)
スレッドセーフな処理ならtrueを返して問題ないと思いますが、今回は先人に習いfalseにしておきました。

ProcessRequestが処理の実体です。
レスポンスに「Hello World」と書き込んでやります。


コンパイルはこんなバッチを作成して行いました。

・build.bat


@echo off
set csc="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe"
set opt=/nologo /t:library

%csc% %opt% Sample.cs




バッチを実行するとSample.dllが生成されます。




ハンドラーの設定



作成したハンドラーをIIS設定してみます。

ハンドラーを有効化するWeb.configを作成。
C:\inetpub\wwwrootに配置します。

・Web.config


  1. <configuration>
  2. <system.webServer>
  3.     <handlers>
  4.      <add verb="*" path="*.hello"
  5.         name="hello_handler"
  6.         type="Sample.MyHandler"/>
  7.     </handlers>
  8. </system.webServer>
  9. </configuration>




verb:このハンドラーを有効にするmethod。
GETやPOSTのみに反応させる場合は指定しますが、今回はすべて(*)を指定しています。

path:このハンドラーを反応させる要求パス。
「*.hello」としているので、拡張子がhelloのURLの場合に反応します。
「target/*.hello」のようにURLを含めた指定も可能です。

name:このハンドラーを識別するための名前。
他のハンドラーと重複しない任意の名称を設定します。

type:ハンドラークラス
今回作成したハンドラーは「Sample」名前空間の「MyHandler」クラスなので「Sample.MyHandler」と指定します。
名前空間がない場合は単に「MyHandler」のように指定すればOKです。


続いて、「C:\inetpub\wwwroot\bin」フォルダを作成。
ビルドした「Sample.dll」を配置します。

最終的にC:\inetpub\wwwrootはこのようになります。
※仮想ディレクトリにハンドラーを設定たい場合は、該当仮想ディレクトリに同じ構成で配置します。


C:\inetpub\wwwroot\
Web.config
\bin\Sample.dll



804_02.png

804_03.png


ここまで設定できたら、IISマネージャーを表示。
Default Web Siteの「ハンドラーマッピング」をダブルクリック。

804_04.png


「hello_handler」が認識されています。

804_05.png


ここで、「ページに関連する構成データが無効であるため、要求されたページにアクセスできません。」という
エラーが表示される場合は、ASP.NET 4.6がインストールされていない可能性が高いです。
ちゃんとASP.NET 4.6やISAPI拡張がインストールされているか確認します。


これでハンドラーの設定は完了です。





動作テスト



トップページを表示。

804_06.png


http://[server]/sample.testを表示すると404エラー。

804_07.png


ハンドラーに登録した拡張子http://[server]/sample.helloを表示すると
「Hello World」と表示されます。

804_08.png




リダイレクト



リダイレクトしたい場合はこんなプログラムになります。


  1. using System.Web;
  2. namespace Sample {
  3.     
  4.     public class MyHandler : System.Web.IHttpHandler {
  5.         
  6.         public bool IsReusable {
  7.             get { return false; }
  8.         }
  9.         
  10.         public void ProcessRequest(HttpContext context) {
  11.             //context.Response.ContentType = "text/html";
  12.             //context.Response.Write("Hello World");
  13.             
  14.             // リダイレクト
  15.             HttpContext.Current.Response.Redirect("https://www.google.co.jp/");
  16.         }
  17.     }
  18. }




拡張子helloだとリダイレクト。

804_09.png

804_10.png





データベース接続



こちらでOracleに接続してみました。
C#からOracle 11g XEへODP.NETで接続

ハンドラー内でデータベースに接続するような処理も実行できるのか試してみます。


  1. using System.Web;
  2. using Oracle.ManagedDataAccess.Client;
  3. namespace Sample {
  4.     
  5.     public class MyHandler : System.Web.IHttpHandler {
  6.         
  7.         public bool IsReusable {
  8.             get { return false; }
  9.         }
  10.         
  11.         public void ProcessRequest(HttpContext context) {
  12.             //context.Response.ContentType = "text/html";
  13.             //context.Response.Write("Hello World");
  14.             
  15.             // リダイレクト
  16.             //HttpContext.Current.Response.Redirect("https://www.google.co.jp/");
  17.             
  18.             // データベース接続
  19.             context.Response.ContentType = "text/html";
  20.             
  21.             OracleConnection con = new OracleConnection();
  22.             string dataSource = "(DESCRIPTION = (ADDRESS_LIST = (ADDRESS=(PROTOCOL = TCP)(HOST = 192.168.1.101)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = XE)))";
  23.             
  24.             con.ConnectionString = "User ID=orauser; Password=Passw0rd; Data Source=" + dataSource + ";";
  25.             con.Open();
  26.             
  27.             string sql = "SELECT * FROM sample";
  28.             OracleCommand cmd = new OracleCommand(sql, con);
  29.             
  30.             OracleDataReader reader = cmd.ExecuteReader();
  31.             while ( reader.Read() ) {
  32.                 context.Response.Write(string.Format("{0}:{1}<br>", reader["id"], reader["val"]));
  33.             }
  34.             
  35.             reader.Close();
  36.             con.Close();
  37.         }
  38.     }
  39. }




C:\inetpub\wwwroot\\binに「Oracle.ManagedDataAccess.dll」をコピー。

804_11.png


うまく行きました。

804_12.png


Cookieの内容を読み取って、まだログインしていなかったらログイン画面へ。
Cookieに設定している内容でデータベースに問い合わせて、閲覧権限をチェック。
...といったこともハンドラーで実施できそうです。



【参考URL】

IIS + ASP.NET 本番サーバ移行のトラブル備忘録
このハンドラーに対して指定されたモジュールが、モジュールの一覧にありません。
IHttpModuleとIHttpHandle
.NETでコントローラを作ってみる
HTTP ハンドラと HTTP モジュールの概要
チュートリアル : 同期 HTTP ハンドラーの作成

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2017/11/08(水) 23:33:16|
  2. 備忘録
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
次のページ