Apache

ApacheとResinとStruts2とFlex(BlazeDS)の連携

メモしときます。

Project名はHello。
HelloWorld ! を表示します。


[ resin.conf ]
----------
# web-appのRoot設定
<web-app id="/" root-directory='C:\Documents and Settings\hoehoe\My Documents\EclipseProject\Hello'/>
----------


[ WEB-INF/lib/ ]
----------
aopalliance-1.0.jar
asm-2.2.3.jar
backport-util-concurrent.jar
cglib-nodep-2.1_3.jar
commons-beanutils.jar
commons-dbcp-1.4.jar
commons-digester.jar
commons-fileupload-1.2.1.jar
commons-io-1.3.2.jar
commons-logging-1.1.1.jar
commons-pool-1.5.4.jar
cxf-2.2.9.jar
dir.txt
FastInfoset-1.2.7.jar
flex-messaging-common.jar
flex-messaging-core.jar
flex-messaging-remoting.jar
freemarker-2.3.16.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-servlet_2.5_spec-1.2.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
geronimo-ws-metadata_2.0_spec-1.1.2.jar
ibatis-2.3.4.726.jar
javassist.jar
jaxb-api-2.1.jar
jaxb-impl-2.1.13.jar
jcommon-1.0.16.jar
log4j-1.2.16.jar
log4j.dtd
neethi-2.0.4.jar
ognl-3.0.jar
opensaml-1.1.jar
pjl-comp-filter-1.7.jar
postgresql-8.3-603.jdbc4.jar
saaj-api-1.3.jar
saaj-impl-1.3.2.jar
serializer-2.7.1.jar
spring-aop.jar
spring-beans.jar
spring-context-support.jar
spring-context.jar
spring-core.jar
spring-jdbc.jar
spring-jms.jar
spring-orm.jar
spring-test.jar
spring-tx.jar
spring-web.jar
sql-map-2.dtd
sql-map-config-2.dtd
struts2-convention-plugin-2.2.1.jar
struts2-core-2.2.1.jar
wsdl4j-1.6.2.jar
wss4j-1.5.8.jar
wstx-asl-3.2.9.jar
xalan-2.7.1.jar
xml-resolver-1.2.jar
XmlSchema-1.4.5.jar
xmlsec-1.4.3.jar
xwork-core-2.2.1.jar
----------




[ web.xml ]
----------
<?xml version="1.0"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
                      http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <!-- Flex(BlazeDSもFilter経由。先にBlazeDSのFilterを記述しておくこと) -->
    <filter>
        <filter-name>flex</filter-name>
        <filter-class>hello.filter.FlexFilter</filter-class>
        <init-param>
            <param-name>services.configuration.file</param-name>
            <param-value>/WEB-INF/flex/services-config.xml</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>flex</filter-name>
        <url-pattern>/messagebroker/*</url-pattern>
    </filter-mapping>


    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>
            org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
        </filter-class>
        <init-param>
            <param-name>actionPackages</param-name>
            <param-value>hello.action</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/struts2/*</url-pattern>
    </filter-mapping>
</web-app>
[EOF]
----------


Struts2の配置 アノテーションを使用するのでstruts.xmlなどは無いです。

[ hello.action.HelloAction ]
----------
package hello.action;

import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;

import com.opensymphony.xwork2.ActionSupport;

/**
 * 相変わらず標準出力に欧米の挨拶をかますだけのアクション。
 */
@Namespace("/struts2")
@Results({
    @Result(name="success", location="hello.jsp"),
    @Result(name="failure", location="error.jsp")
})
public class HelloAction extends ActionSupport {
//public class SayHelloAction {
    private static final long serialVersionUID = 1L;

    /**
     * アクション実行メソッド。
     */
    public String execute() {
        // アクション実行の結果を文字列で返す。
        return ActionSupport.SUCCESS;
    }
    public String getMessage(){
        return "Hello World!!";
    }
}
[ EOF ]
----------


[ /WEB-INF/content/struts2/hello.jsp ]
----------
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:property value="message"/>
</body>
</html>
[ EOF ]
----------


[ hello.filter.FlexFilter ]
----------
package hello.filter;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.mock.web.MockServletConfig;

import flex.messaging.MessageBrokerServlet;

/**
 * The MessageBrokerServlet has a lower priority than Filters, regardless of the
 * url-pattern we use. For that reason I created a filter that directly extends
 * the MessageBrokerServlet but behaves as a filter. This might be quite dodgy
 * but that's the only way I found to integrate struts 2 and Adobe Flex/BlazeDS.
 * Anyone who knows a simpler way please email me at info at spltech.co.uk
 *
 * @author Armindo Cachada
 *
 */
public class FlexFilter extends MessageBrokerServlet implements Filter {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    public void destroy() {
        super.destroy();
    }

    /**
     * If this method is called the parent service method of the
     * MessageBrokerServlet is called, which does whatever BlazeDS needs to do
     * to communicate with the flex client. Note Here that any subsequent filter
     * will not be called because I am not invoking filterChain.doFilter/ That
     * is on purpose, because if it does, the normal struts 2 action mapping
     * mechanism will be called.
     *
     */
    public void doFilter(ServletRequest servletrequest,
            ServletResponse servletresponse, FilterChain filterchain)
            throws IOException, ServletException {
        this.service((HttpServletRequest) servletrequest,
                (HttpServletResponse) servletresponse);
    }

    /**
     * Note the use here of MockServletConfig. This utility class is available
     * in the spring framework. It is meant to be used for testing but I am
     * actually giving it a real purpose :)
     */
    public void init(FilterConfig filterconfig) throws ServletException {
        System.out.println("filter called");
        MockServletConfig servletConfig = new MockServletConfig(filterconfig
                .getServletContext());
        Enumeration filterParameters = filterconfig.getInitParameterNames();

        while (filterParameters.hasMoreElements()) {
            String filterParameter = (String) filterParameters.nextElement();
            System.out.println("Found parameter: " + filterParameter);
            String value = filterconfig.getInitParameter(filterParameter);
            servletConfig.addInitParameter(filterParameter, value);

        }
        super.init(servletConfig);
    }

}
[ EOF ]
----------


[ /WEB-INF/flex/services-config.xml ]
----------
<?xml version="1.0" encoding="UTF-8"?>
<services-config>

    <services>
        <!-- service要素には何でもいいからIDが要る模様 -->
        <service id="remoting-service"
            class="flex.messaging.services.RemotingService">
            <adapters>
                <adapter-definition id="java-object"
                    class="flex.messaging.services.remoting.adapters.JavaAdapter"
                    default="true" />
            </adapters>
            <default-channels>
                <channel ref="my-amf" />
                <channel ref="my-secure-amf"/>
            </default-channels>

            <!-- destination要素のIDが mx:RemoteObjectの destination プロパティに対応する -->
            <!-- リモート呼び出しを可能にしたい Beanの数だけ destination要素を記述する -->
            <destination id="fxService">
                <properties>
                    <!-- リモート呼び出ししたいJava Beansのクラス名 -->
                    <source>hello.ws.FlexService</source>
                    <!-- 注:この Beanはステートレスである -->
                </properties>
            </destination>
        </service>
    </services>

    <channels>
        <channel-definition id="my-amf"
            class="mx.messaging.channels.AMFChannel">
            <!--
                ここで構成されたエンドポイントURLを mx:RemoteObjectの
                endpoint プロパティにセットする
                {}内は実行時に自動で置き換えられるのでこの記述のままで良い。
            -->
            <endpoint
                url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf"
                class="flex.messaging.endpoints.AMFEndpoint" />
            <properties>
                <add-no-cache-headers>false</add-no-cache-headers>
            </properties>
        </channel-definition>

        <!-- SSL用チャンネルの定義 -->
        <channel-definition id="my-secure-amf" class="mx.messaging.channels.SecureAMFChannel">
            <endpoint url="https://{server.name}:{server.port}/{context.root}/messagebroker/amfsecure" class="flex.messaging.endpoints.SecureAMFEndpoint"/>
            <properties>
                <add-no-cache-headers>false</add-no-cache-headers>
            </properties>
        </channel-definition>
    </channels>
</services-config>
[ EOF ]
----------


[ hello.ws.FlexService ]
----------
package hello.ws;

@SuppressWarnings("serial")
public class FlexService implements java.io.Serializable{
        
    public FlexService(){
    }
    public String sayHello(){
        return "Hello World !";
    }
}
[ EOF ]
----------



Apache
[ httpd.conf -Apache- ]
----------
#
# mod_caucho Resin Configuration
#
#Include conf/extra/httpd-proxy.conf
LoadModule caucho_module /usr/local/apache/modules/mod_caucho.so

ResinConfigServer 127.0.0.1 6800
CauchoConfigCacheDirectory /tmp
CauchoStatus yes
<Location /struts2/*>
  SetHandler caucho-request
</Location>
[ EOF ]
----------


Flex
[ Hello.mxml ]
----------
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundColor="white" creationComplete="init();">
<mx:Script source="Hello.as"/>
    <mx:RemoteObject id="srv" endpoint="{lbl_endPoint.text}" destination="fxService" showBusyCursor="true">
        <mx:method name="sayHello" result="resultHello(event);" fault="faultHello(event);"/>
    </mx:RemoteObject>
    <mx:Button x="65" y="59" label="click" id="btn_message" click="btn_message_click();"/>
    <mx:Text x="38" y="33" id="txt_message" text="{srv.sayHello.lastResult}"/>
    <mx:Label x="84" y="114" id="lbl_endPoint"/>
</mx:Application>
[ EOF ]
----------

[ Hello.as ]
----------
// ActionScript file
import hello.EndPoint;

import mx.controls.Alert;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;

private function init():void{
    lbl_endPoint.text = EndPoint.getEndPointRevers();
}
private function btn_message_click():void{
    srv.sayHello();
}

private function resultHello(event:ResultEvent):void{
    Alert.show(event.message.toString());
}
private function faultHello(event:FaultEvent):void{
    Alert.show(event.message.toString());
}
[ EOF ]
----------


[ hello.EndPoint.as ]
----------
package hello {

    import flash.external.ExternalInterface;
   
    import mx.messaging.ChannelSet;
    import mx.messaging.channels.AMFChannel;
    import mx.rpc.remoting.mxml.RemoteObject;

    public class EndPoint {
       
        private static var remote:RemoteObject;
       
        public function EndPoint() {
            //TODO: implement function
        }
        public static function getEndPointRevers():String{
            var endPointURL:String = ExternalInterface.call("getFQDN");
            endPointURL = endPointURL + "messagebroker/amf";
            return endPointURL;
        }
        public static function getRemoteObject():RemoteObject{
            //var remote:RemoteObject = new RemoteObject();
            if(remote == null){
                remote = new RemoteObject();
                var cs:ChannelSet = new ChannelSet();
                var ac:AMFChannel = new AMFChannel("my-amf", EndPoint.getEndPointRevers());
                cs.addChannel(ac);
                remote.destination = "flexService";
                remote.channelSet = cs;
            }
            return remote;
        }
    }
}
[ EOF ]
----------

[ index.template.html(JavaScript) ]
----------
<script language="JavaScript" type="text/javascript">
<!--
//------------------------------------------------------------------------------
// MyScript
function setTitle(){
    if(location.href.indexOf("#",0) == -1){
        document.title = "IntraMaster";
    }else{
        document.title = "IntraMaster";
    }
}
function getURL(){
    return (document.URL);
}
function getPort(){
    var protocol = location.protocol;
    var port = location.port;
   
    if(protocol == "http:"){
        if(port == ""){
            port = 80;
        }else{
       
        }
    }else if(protocol == "https:"){
        if(port == ""){
            port = 443;
        }else{
       
        }       
    }
   
    return port;
}
function getFQDN(){
    var fqdn = "";
    var hostname = location.hostname;
    var protocol = location.protocol;
    var port = location.port;
    var href= location.href;
   
    var a;
    var b;
   
    var lastIndex = href.lastIndexOf("/");
    href = href.substring(0, lastIndex);
   
    if(href.indexOf("~") == -1){
        if(port == ""){
            fqdn = protocol + "//" + hostname + "/"
        }else{
            fqdn = protocol + "//" + hostname + ":" + port + "/"
        }
    }else{
        a = href.split("//")[1];
        b = a.split("/")[1];
        if(port == ""){
            fqdn = protocol + "//" + hostname + "/" + b;
        }else{
            fqdn = protocol + "//" + hostname + ":" + port + "/" + b;
        }
    }
    //fqdn = "http://127.0.0.1:8081/messagebroker/amf";
    return fqdn;
}

function getUserAgent(){
    var ua = navigator.userAgent;
    var strOS;
   
    if(ua.indexOf("Win") >= 0){ strOS = "Win"; }
    else if(ua.indexOf("Mac") >= 0){ strOS = "Mac"; }
    else if(ua.indexOf("Linux") >= 0){ strOS = "Linux"; }
    else{ strOS = ""; }

    return strOS;
}

//------------------------------------------------------------------------------
//-->
</script>
[ EOF ]
----------
 
Tomcatと連携する場合はApacheのコンパイル時に ./configure --enable-proxy --enable-proxy-ajp を有効にし、
/usr/local/apache2/conf/extra/httpd-proxy.conf を新規に作成後、以下を記述保存します。

以下の例では、/struts2/* ( /struts2以下のすべてのリクエスト ) に対して ProxyPass を設定しています。

<Location /struts2/>
ProxyPass ajp://localhost:8009/
</Location>

1. FreeBSD6.2, Apache1.3.42, PHP5.3, Python2.7, mod_python にてApacheがSegmentation Faultで落ちる。
2. Pythonは--without-thread指定しないとコンパイルが通らない。
3. mod_pythonの代わりにmod_wsgiをインストールしようとしたが、--without-threadを付けてPythonをインストール後 mod_wsgiをインストールしようとすると、PythonのThreadを有効にしてインストールしろと怒られる...。


どうしろと?という状況になったので、OSから全部新規にやり直し。


FreeBSD8.1, Apache2.2.16, PHP5.3, MySQL5.1, Python2.6.5, mod_wsgi3.3 で動きました。(FreeBSD7.3で新規に書き下ろした解決方法はこちら)


以下操作ログ。

あー、 ちなみに、mod_pythonのSegmentation Faultだが、今回は 「mod_pythonとPHP, MySQLがインストールされているとSegmentation Fault(11)でApacheが落ちる」という迷惑極まりない代物。諦めましょう。

http://djangoproject.jp/doc/ja/1.0/howto/deployment/modpython.html#id11 によると、
『mod_python と mod_php を同じ Apache のインスタンスで動作させ、バックエンドに MySQL を使っている場合。PHP と Python MySQL バックエンドとのバージョン衝突で引き起こされる既知の問題かもしれません。これについては mod_python FAQ entry に詳しく書かれています。』とのこと。


[root@bsd ~]# uname -a
FreeBSD bsd.local 8.1-RELEASE FreeBSD 8.1-RELEASE #0: Mon Jul 19 02:55:53 UTC 2010     root@almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386



- ports更新 -
[root@bsd ~]# portsnap fetch
[root@bsd ~]# portsnap extract


- postgresqlインストール -
[root@bsd ~]# pushd /usr/local/src/
[root@bsd ~]# wget http://wwwmaster.postgresql.org/redir/323/f/source/v8.4.4/postgresql-8.4.4.tar.gz
[root@bsd ~]# tar xzf postgresql-8.4.4.tar.gz
[root@bsd ~]# cd postgresql-8.4.4
[root@bsd ~]# ./configure --prefix=/usr/local/pgsql
[root@bsd ~]# make
[root@bsd ~]# make install
[root@bsd ~]# make clean
[root@bsd ~]# adduser postgres
[root@bsd ~]# /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
[root@bsd ~]# chown postgres:postgres /usr/local/pgsql
[root@bsd ~]# chown -R postgres:postgres /usr/local/pgsql


- MySQLインストール -
[root@bsd ~]# pushd /usr/local/src/
[root@bsd ~]# wget http://chocbanana.com/mysql-5.1.50.tar.gz
[root@bsd ~]# tar xzf mysql-5.1.50.tar.gz
[root@bsd ~]# cd mysql-5.1.50
[root@bsd ~]# ./configure --prefix=/usr/local/mysql
[root@bsd ~]# make
[root@bsd ~]# make install
[root@bsd ~]# make clean
[root@bsd ~]# cp support-files/mysql.server.sh /usr/local/etc/rc.d/mysql-server
[root@bsd ~]# cp /usr/local/src/mysql-5.1.50/support-files/my-medium.cnf.sh /etc/my.cnf
[root@bsd ~]# vi /etc/my.cnf
[root@bsd ~]# /usr/local/etc/rc.d/mysql-server start


- webalizerインストール -
[root@bsd ~]# pushd /usr/ports/www/webalizer/
[root@bsd ~]# make
[root@bsd ~]# make install
[root@bsd ~]# make clean

- libmcrypt / PHPのconfigureで指定するためインストール -
[root@bsd ~]# pushd /usr/ports/security/libmcrypt/
[root@bsd ~]# make
[root@bsd ~]# make install clean


- Python2.6.5 インストール -
[root@bsd ~]# pushd /usr/ports/lang/python
[root@bsd ~]# make fetch
[root@bsd ~]# make config # ここで Enable thread supportを有効にすること
[root@bsd ~]# make patch
[root@bsd ~]# make
[root@bsd ~]# make install
[root@bsd ~]# make clean


- Apache2.2.16インストール -
[root@bsd ~]# pushd /usr/local/src/
[root@bsd ~]# wget http://chocbanana.com/dl/httpd-2.2.16.tar.gz
[root@bsd ~]# tar xzf httpd-2.2.16.tar.gz
[root@bsd ~]# cd httpd-2.2.16

[root@bsd ~]# ./configure --prefix=/usr/local/apache2  --enable-suexec --with-suexec-caller=nobody --with-suexec-userdir=homepage --with-suexec-docroot=/home  --with-suexec-logfile=/usr/local/apache2/logs/suexec_log --with-suexec-uidmin=1000 --with-suexec-gidmin=1000 --with-suexec-safepath="/bin:/usr/bin"  --enable-module=log_agent --enable-module=log_referer --enable-module=so --enable-module=rewrite --enable-rule=SHARED_CORE  --enable-rule=EXPAT

[root@bsd ~]# make
[root@bsd ~]# make install
[root@bsd ~]# make clean



- PHP5.3.3インストール -
[root@bsd ~]# cd ../
[root@bsd ~]# wget http://chocbanana.com/dl/php-5.3.3.tar.gz
[root@bsd ~]# tar xzf php-5.3.3.tar.gz
[root@bsd ~]# cd php-5.3.3
[root@bsd ~]# ./configure --enable-mbstring --enable-mbregex --with-apxs2=/usr/local/apache2/bin/apxs --with-pgsql=/usr/local/pgsql --with-mysql=/usr/local/mysql --with-gd --with-zlib --with-jpeg-dir=/usr/local/lib --with-png-dir=/usr/local/lib --with-freetype-dir=/usr/local --with-mcrypt=/usr/local

[root@bsd ~]# make
[root@bsd ~]# make test
[root@bsd ~]# make install
[root@bsd ~]# make clean

- mod_wsgiインストール(ApacheとPythonのコネクタ) -
[root@bsd ~]# cd ../
[root@bsd ~]# wget http://chocbanana.com/dl/mod_wsgi-3.3.tar.gz
[root@bsd ~]# tar xzf mod_wsgi-3.3.tar.gz
[root@bsd ~]# cd mod_wsgi-3.3
[root@bsd ~]# ./configure --with-apxs=/usr/local/apache2/bin/apxs
[root@bsd ~]# make
[root@bsd ~]# make install



[root@bsd ~]# vi /usr/local/apache2/conf/httpd.conf


[ httpd.conf ]
-----
# Example:
# LoadModule foo_module modules/mod_foo.so
LoadModule php5_module        modules/libphp5.so
LoadModule wsgi_module        modules/mod_wsgi.so
-----


[root@bsd ~]# /usr/local/apache2/bin/apachectl configtest
[root@bsd ~]# /usr/local/apache2/bin/apachectl start


[ error_log ]
-----
[Sat Aug 28 21:06:23 2010] [notice] suEXEC mechanism enabled (wrapper: /usr/local/apache2/bin/suexec)
[Sat Aug 28 21:06:23 2010] [notice] Apache/2.2.16 (Unix) mod_wsgi/3.3 Python/2.6.5 PHP/5.3.3 configured -- resuming normal operations
-----

  Apache/2.2.16 (Unix) mod_wsgi/3.3 Python/2.6.5 PHP/5.3.3 configured と表示されていればOK。

  ■追記
      FreeBSD6.2で、HyperThreadingなどCPUが(擬似的な場合も含む)2つ以上の場合にPythonのコンパイルが通らない可能性が ある。
      SMP環境下でPHP, Python, MySQLを構築するには、OSのアップグレードが必要になると思います。
      # SMP環境下だとmod_wsgi3.3でも Segmentation fault(11) でApache落ちたよ。
      # つか、FreeBSD8.1ならSMPでも大丈夫だったので、OSアップグレードして下さい...。orz


もう完全にメモ。殴り書き。

[ mysql ]
# tar xzf mysql-5.1.43.tar.gz
# cd mysql-5.1.43
# ./configure --prefix=/usr/local/mysql -with-charset=utf8 -with-extra-charsets=all
# make; make install; make clean

[ postgresql ]
# tar xzf postgresql-8.4.2.tar.gz
# cd postgresql-8.4.2
# ./configure --prefix=/usr/local/pgsql
# make; make install; make clean


[ openssl ]
# ./config --prefix=/usr/local/openssl enable-tlsext; make depend; make; make install; make clean;

[ apache ]
# ./configure --prefix=/usr/local/apache --enable-so --enable-ssl --with-ssl=/usr/local/openssl --enable-deflate
# make; make install; make clean

[ php ]
# ./configure --prefix=/usr/local/php --with-apxs2=/usr/local/apache/bin/apxs --with-mysql=/usr/local/mysql --with-pgsql=/usr/local/pgsql --enable-mbstring --enable-mbregex
# make; make install; make clean
# cp php.ini-production /usr/local/php/lib/php.ini

[ php.ini ]
----
[mbstring]
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.http_input = auto
mbstring.http_output = UTF-8
mbstring.encoding_translation = On
mbstring.detect_order = auto
mbstring.substitute_character = none;
mbstring.script_encoding=auto
----

[ httpd.conf ]
----
DirectoryIndex index.html index.php
AddType application/x-httpd-php .php
----

[ index.php ]
----
<?php phpinfo() ?>
----

Apacheのmod_deflateでGzip圧縮...です。
以下作業内容。


# ./configure --prefix=/usr/local/apache --enable-so --enable-ssl --with-ssl=/usr/local/openssl --enable-deflate --enable-rewrite --enable-headers
# make
# make install clean
# /usr/local/apache/bin/httpd -l

# cd /usr/local/apache/conf/
# vi httpd.conf

[ httpd.conf ]
---------
#
# This is the main Apache HTTP server configuration file.  It contains the
# configuration directives that give the server its instructions.
# See <URL:http://httpd.apache.org/docs/2.2> for detailed information.
# In particular, see
# <URL:http://httpd.apache.org/docs/2.2/mod/directives.html>
# for a discussion of each configuration directive.
#
# Do NOT simply read the instructions in here without understanding
# what they do.  They're here only as hints or reminders.  If you are unsure
# consult the online docs. You have been warned.  
#
# Configuration and logfile names: If the filenames you specify for many
# of the server's control files begin with "/" (or "drive:/" for Win32), the
# server will use that explicit path.  If the filenames do *not* begin
# with "/", the value of ServerRoot is prepended -- so "logs/foo_log"
# with ServerRoot set to "/usr/local/apache" will be interpreted by the
# server as "/usr/local/apache/logs/foo_log".

#
# ServerRoot: The top of the directory tree under which the server's
# configuration, error, and log files are kept.
#
# Do not add a slash at the end of the directory path.  If you point
# ServerRoot at a non-local disk, be sure to point the LockFile directive
# at a local disk.  If you wish to share the same ServerRoot for multiple
# httpd daemons, you will need to change at least LockFile and PidFile.
#
ServerRoot "/usr/local/apache"

#
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 12.34.56.78:80
Listen 80

#
# Dynamic Shared Object (DSO) Support
#
# To be able to use the functionality of a module which was built as a DSO you
# have to place corresponding `LoadModule' lines at this location so the
# directives contained in it are actually available _before_ they are used.
# Statically compiled modules (those listed by `httpd -l') do not need
# to be loaded here.
#
# Example:
# LoadModule foo_module modules/mod_foo.so
#

<IfModule !mpm_netware_module>
<IfModule !mpm_winnt_module>
#
# If you wish httpd to run as a different user or group, you must run
# httpd as root initially and it will switch.  
#
# User/Group: The name (or #number) of the user/group to run httpd as.
# It is usually good practice to create a dedicated user and group for
# running httpd, as with most system services.
#
User nobody
Group nobody

</IfModule>
</IfModule>

# 'Main' server configuration
#
# The directives in this section set up the values used by the 'main'
# server, which responds to any requests that aren't handled by a
# <VirtualHost> definition.  These values also provide defaults for
# any <VirtualHost> containers you may define later in the file.
#
# All of these directives may appear inside <VirtualHost> containers,
# in which case these default settings will be overridden for the
# virtual host being defined.
#

#
# ServerAdmin: Your address, where problems with the server should be
# e-mailed.  This address appears on some server-generated pages, such
# as error documents.  e.g. admin@your-domain.com
#
ServerAdmin you@example.com

#
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
#
#ServerName www.example.com:80

#
# DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.
#
DocumentRoot "/usr/local/apache/htdocs"

#
# Each directory to which Apache has access can be configured with respect
# to which services and features are allowed and/or disabled in that
# directory (and its subdirectories).
#
# First, we configure the "default" to be a very restrictive set of
# features.  
#
<Directory />
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
</Directory>

#
# Note that from this point forward you must specifically allow
# particular features to be enabled - so if something's not working as
# you might expect, make sure that you have specifically enabled it
# below.
#

#
# This should be changed to whatever you set DocumentRoot to.
#
<Directory "/usr/local/apache/htdocs">
    #
    # Possible values for the Options directive are "None", "All",
    # or any combination of:
    #   Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
    #
    # Note that "MultiViews" must be named *explicitly* --- "Options All"
    # doesn't give it to you.
    #
    # The Options directive is both complicated and important.  Please see
    # http://httpd.apache.org/docs/2.2/mod/core.html#options
    # for more information.
    #
    Options Indexes FollowSymLinks

    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    #
    AllowOverride None

    #
    # Controls who can get stuff from this server.
    #
    Order allow,deny
    Allow from all

</Directory>

#
# DirectoryIndex: sets the file that Apache will serve if a directory
# is requested.
#
<IfModule dir_module>
    DirectoryIndex index.html
</IfModule>

#
# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
#
<FilesMatch "^\.ht">
    Order allow,deny
    Deny from all
    Satisfy All
</FilesMatch>

#
# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a <VirtualHost>
# container, error messages relating to that virtual host will be
# logged here.  If you *do* define an error logfile for a <VirtualHost>
# container, that host's errors will be logged there and not here.
#
ErrorLog "logs/error_log"

#
# LogLevel: Control the number of messages logged to the error_log.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
#
LogLevel warn

<IfModule log_config_module>
    #
    # The following directives define some format nicknames for use with
    # a CustomLog directive (see below).
    #
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common

    <IfModule logio_module>
      # You need to enable mod_logio.c to use %I and %O
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>

    #
    # The location and format of the access logfile (Common Logfile Format).
    # If you do not define any access logfiles within a <VirtualHost>
    # container, they will be logged here.  Contrariwise, if you *do*
    # define per-<VirtualHost> access logfiles, transactions will be
    # logged therein and *not* in this file.
    #
    CustomLog "logs/access_log" common

    #
    # If you prefer a logfile with access, agent, and referer information
    # (Combined Logfile Format) you can use the following directive.
    #
    #CustomLog "logs/access_log" combineda

    DeflateFilterNote Input instream
    DeflateFilterNote Output outstream
    DeflateFilterNote Ratio ratio
    LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%) %{User-agent}i' deflate
    CustomLog logs/deflate_log deflate
</IfModule>

<IfModule alias_module>
    #
    # Redirect: Allows you to tell clients about documents that used to
    # exist in your server's namespace, but do not anymore. The client
    # will make a new request for the document at its new location.
    # Example:
    # Redirect permanent /foo http://www.example.com/bar

    #
    # Alias: Maps web paths into filesystem paths and is used to
    # access content that does not live under the DocumentRoot.
    # Example:
    # Alias /webpath /full/filesystem/path
    #
    # If you include a trailing / on /webpath then the server will
    # require it to be present in the URL.  You will also likely
    # need to provide a <Directory> section to allow access to
    # the filesystem path.

    #
    # ScriptAlias: This controls which directories contain server scripts.
    # ScriptAliases are essentially the same as Aliases, except that
    # documents in the target directory are treated as applications and
    # run by the server when requested rather than as documents sent to the
    # client.  The same rules about trailing "/" apply to ScriptAlias
    # directives as to Alias.
    #
    ScriptAlias /cgi-bin/ "/usr/local/apache/cgi-bin/"

</IfModule>

<IfModule cgid_module>
    #
    # ScriptSock: On threaded servers, designate the path to the UNIX
    # socket used to communicate with the CGI daemon of mod_cgid.
    #
    #Scriptsock logs/cgisock
</IfModule>

#
# "/usr/local/apache/cgi-bin" should be changed to whatever your ScriptAliased
# CGI directory exists, if you have that configured.
#
<Directory "/usr/local/apache/cgi-bin">
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all
</Directory>

#
# DefaultType: the default MIME type the server will use for a document
# if it cannot otherwise determine one, such as from filename extensions.
# If your server contains mostly text or HTML documents, "text/plain" is
# a good value.  If most of your content is binary, such as applications
# or images, you may want to use "application/octet-stream" instead to
# keep browsers from trying to display binary files as though they are
# text.
#
DefaultType text/plain

<IfModule mime_module>
    #
    # TypesConfig points to the file containing the list of mappings from
    # filename extension to MIME-type.
    #
    TypesConfig conf/mime.types

    #
    # AddType allows you to add to or override the MIME configuration
    # file specified in TypesConfig for specific file types.
    #
    #AddType application/x-gzip .tgz
    #
    # AddEncoding allows you to have certain browsers uncompress
    # information on the fly. Note: Not all browsers support this.
    #
    #AddEncoding x-compress .Z
    #AddEncoding x-gzip .gz .tgz
    #
    # If the AddEncoding directives above are commented-out, then you
    # probably should define those extensions to indicate media types:
    #
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz

    #
    # AddHandler allows you to map certain file extensions to "handlers":
    # actions unrelated to filetype. These can be either built into the server
    # or added with the Action directive (see below)
    #
    # To use CGI scripts outside of ScriptAliased directories:
    # (You will also need to add "ExecCGI" to the "Options" directive.)
    #
    #AddHandler cgi-script .cgi

    # For type maps (negotiated resources):
    #AddHandler type-map var

    #
    # Filters allow you to process content before it is sent to the client.
    #
    # To parse .shtml files for server-side includes (SSI):
    # (You will also need to add "Includes" to the "Options" directive.)
    #
    #AddType text/html .shtml
    #AddOutputFilter INCLUDES .shtml
</IfModule>

#
# The mod_mime_magic module allows the server to use various hints from the
# contents of the file itself to determine its type.  The MIMEMagicFile
# directive tells the module where the hint definitions are located.
#
#MIMEMagicFile conf/magic

#
# Customizable error responses come in three flavors:
# 1) plain text 2) local redirects 3) external redirects
#
# Some examples:
#ErrorDocument 500 "The server made a boo boo."
#ErrorDocument 404 /missing.html
#ErrorDocument 404 "/cgi-bin/missing_handler.pl"
#ErrorDocument 402 http://www.example.com/subscription_info.html
#

#
# EnableMMAP and EnableSendfile: On systems that support it,
# memory-mapping or the sendfile syscall is used to deliver
# files.  This usually improves server performance, but must
# be turned off when serving from networked-mounted
# filesystems or if support for these functions is otherwise
# broken on your system.
#
#EnableMMAP off
#EnableSendfile off

# Supplemental configuration
#
# The configuration files in the conf/extra/ directory can be
# included to add extra features or to modify the default configuration of
# the server, or you may simply copy their contents here and change as
# necessary.

# Server-pool management (MPM specific)
#Include conf/extra/httpd-mpm.conf

# Multi-language error messages
#Include conf/extra/httpd-multilang-errordoc.conf

# Fancy directory listings
#Include conf/extra/httpd-autoindex.conf

# Language settings
#Include conf/extra/httpd-languages.conf

# User home directories
#Include conf/extra/httpd-userdir.conf

# Real-time info on requests and configuration
#Include conf/extra/httpd-info.conf

# Virtual hosts
#Include conf/extra/httpd-vhosts.conf

# Local access to the Apache HTTP Server Manual
#Include conf/extra/httpd-manual.conf

# Distributed authoring and versioning (WebDAV)
#Include conf/extra/httpd-dav.conf

# Various default settings
#Include conf/extra/httpd-default.conf

# Secure (SSL/TLS) connections
#Include conf/extra/httpd-ssl.conf
#
# Note: The following must must be present to support
#       starting without SSL on platforms with no /dev/random equivalent
#       but a statically compiled-in mod_ssl.
#
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>


Include conf/extra/httpd-my.conf

#
# mod_caucho Resin Configuration
#

LoadModule caucho_module /usr/local/apache/modules/mod_caucho.so

ResinConfigServer localhost 6800
CauchoConfigCacheDirectory /tmp
CauchoStatus yes

<IfModule mod_deflate.c>
        # mod_deflate
        AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-amf
        SetOutputFilter DEFLATE

        BrowserMatch ^Mozilla/4 gzip-only-text/html
        BrowserMatch ^Mozilla/4\.0[678] no-gzip
        BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
        SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|zip|gz)$ no-gzip dont-vary

        # mod_rewrite
        #RewriteEngine on

        #RewriteCond %{HTTP:User-Agent} MSIE\ [56]
        #RewriteCond %{HTTP:User-Agent} !SV1
        #RewriteCond %{REQUEST_URI} \.(css|js)$
        #Header append Vary User-Agent env=!dont-vary
</IfModule>
[ EOF ]
------

# /usr/local/apache/bin/apachectl configtest
# /etc/rc.d/init.d/apache stop
# /etc/rc.d/init.d/apache start

(1)ServerTokens の変更
 ServerTokens ProductOnly <httpd.confへ
 Apache、DB、PHP、OS等の詳細なバージョンを表示しない
 Apache 1.3.12以降

(2)ServerSignature の変更
 ServerSignature Off <httpd.confへ
 DirectoryIndex などに情報が出ないようにする
 Apache 1.3以降

(3)Traceメソッドの無効化
 TraceEnable Off <httpd.confへ
 「クロスサイトトレーシング」対策として
 Apache 1.3.34 と 2.0.55以降



まずはデフォルトでインストールされているOpenSSLで証明書を作成しておきます。

[ 証明書の作成 ]
mkdir ~/keys
cd ~/keys
openssl genrsa -des3 1024 > server.key
openssl rsa -in server.key -out server.key
openssl req -new -key server.key -out server.cert
openssl x509 -in server.cert -out server.cert -req -signkey server.key -days 3650


openssl-0.9.8i.tar.gzが必要になるので、そちらをインストールします。

[ OpenSSL インストール ]
cd /usr/local/src
wget http://www.openssl.org/source/openssl-0.9.8i.tar.gz
tar xzf openssl-0.9.8i.tar.gz
cd openssl-0.9.8i
./config --prefix=/usr/local/openssl enable-tlsext; make depend; make; make install; make clean;


パッチを充てて、Apacheをインストール。

[ Apache2.2 インストール ]
wget http://www.meisei-u.ac.jp/mirror/apache/httpd/httpd-2.2.10.tar.gz
wget https://sni.velox.ch/misc/httpd-2.2.x-sni.patch
tar xzf httpd-2.2.10.tar.gz
cd httpd-2.2.10
patch -p1 < ../httpd-2.2.x-sni.patch
./configure --prefix=/usr/local/apache --enable-so --enable-ssl --with-ssl=/usr/local/openssl
make; make install; make clean
cp ~/keys/* /usr/local/apache/conf/


/usr/local/apache/conf/httpd.conf に下記1行を追記。
[ /usr/local/apache/conf/httpd.conf ]
# My configration
Include conf/extra/httpd-my.conf


httpd-my.confで設定を行う

vi ./conf/extra/httpd-my.conf
-------------------------------
#
# When we also provide SSL we have to listen to the
# standard HTTP port (see above) and to the HTTPS port
#
# Note: Configurations that use IPv6 but not IPv4-mapped addresses need two
#       Listen directives: "Listen [::]:443" and "Listen 0.0.0.0:443"
#
Listen 443

##
##  SSL Global Context
##
##  All SSL configuration in this context applies both to
##  the main server and all SSL-enabled virtual hosts.
##

#
#   Some MIME-types for downloading Certificates and CRLs
#
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl    .crl

#   Pass Phrase Dialog:
#   Configure the pass phrase gathering process.
#   The filtering dialog program (`builtin' is a internal
#   terminal dialog) has to provide the pass phrase on stdout.
#SSLPassPhraseDialog  builtin

#   Inter-Process Session Cache:
#   Configure the SSL Session Cache: First the mechanism
#   to use and second the expiring timeout (in seconds).
#SSLSessionCache         "dbm:/usr/local/apache/logs/ssl_scache"
#SSLSessionCache        "shmcb:/usr/local/apache/logs/ssl_scache(512000)"
#SSLSessionCacheTimeout  300

#   Semaphore:
#   Configure the path to the mutual exclusion semaphore the
#   SSL engine uses internally for inter-process synchronization.
#SSLMutex  "file:/usr/local/apache/logs/ssl_mutex"

#
# Virtual Hosts
NameVirtualHost *:80
NameVirtualHost *:443

<VirtualHost *:80>
    ServerAdmin webmaster@hoge.com
    DocumentRoot "/home/www/v1"
    ServerName v1.hoge.com

    <Directory "/home/www/v1">
        Options Indexes FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

<VirtualHost *:80>
    ServerAdmin webmaster@hoge.com
    DocumentRoot "/home/www/v2"
    ServerName v2.hoge.com

    <Directory "/home/www/v2">
        Options Indexes FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

# Secure Shell ver.
<VirtualHost *:443>
    ServerAdmin webmaster@hoge.com
    DocumentRoot "/home/www/v1"
    ServerName v1.hoge.com:443

    #SSL Engine Switch:
    #Enable/Disable SSL for this virtual host.
    SSLEngine on

    #   Server Private Key:
    #   If the key is not combined with the certificate, use this
    #   directive to point at the key file.  Keep in mind that if
    #   you've both a RSA and a DSA private key you can configure
    #   both in parallel (to also allow the use of DSA ciphers, etc.)
    SSLCertificateFile "/usr/local/apache/conf/server.cert"
    SSLCertificateKeyFile "/usr/local/apache/conf/server.key"

    <Directory "/home/www/v1">
        Options Indexes FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

<VirtualHost *:443>
    ServerAdmin webmaster@hoge.com
    DocumentRoot "/home/www/v2"
    ServerName v2.hoge.com:443

    #SSL Engine Switch:
    #Enable/Disable SSL for this virtual host.
    SSLEngine on

    #   Server Private Key:
    #   If the key is not combined with the certificate, use this
    #   directive to point at the key file.  Keep in mind that if
    #   you've both a RSA and a DSA private key you can configure
    #   both in parallel (to also allow the use of DSA ciphers, etc.)
    SSLCertificateFile "/usr/local/apache/conf/server.cert"
    SSLCertificateKeyFile "/usr/local/apache/conf/server.key"

    <Directory "/home/www/v2">
        Options Indexes FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>
-------------------------------
VirtualHostとSSLを併用する場合は、<VirtualHost *:443><VirtualHost *:80>を必要台数分記述します。


■追記
Apache 2.2.11 の場合は https://sni.velox.ch/misc/ から対応しているパッチを落として充てて下さい。

■追記その2 -2009/10/12-
Apache 2.2.12以降はパッチ適用の必要がなくなりました。
./configure --prefix=/usr/local/apache --enable-so --enable-ssl --with-ssl=/usr/local/openssl;
make; make install; make clean
だけで大丈夫です。opensslはenable-tlsext を指定して下さい。


Apache1.3.x と Apache2.x.x共通。

LogFormatを下記の用に変更することで、CodeRedやNimdaなど414(Request-URI Too Long)なエラーを吐かせる鬱陶しいのを回避することが出来ます。

$APACHE_HOME/conf/httpd.conf の <IfModule log_config_module></IfModule> にあるLogFormatを変更します。

LogFormat "%h %l %u %t \"%!414r\" \"%!400r\" %>s %b" common

このページの先頭へ