🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

1826閲覧

サーバー環境で階層移動ができない

gogotowel

総合スコア9

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

Apache

Apacheは、Apache HTTP Serverの略で、最も人気の高いWebサーバソフトウェアの一つです。安定性が高いオープンソースソフトウェアとして商用サイトから自宅サーバまで、多くのプラットフォーム向けに開発・配布されています。サーバーソフトウェアの不具合(NCSA httpd)を修正するパッチ(a patch)を集積、一つ独立したソフトウェアとして開発されました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2020/12/30 22:52

編集2021/01/01 04:48

知りたいこと

ローカルの環境とサーバー環境で挙動が違う点があり調べています。
カレントの階層を移動させるプログラムを実行すると、サーバー環境では移動が初回実行時しか成功せず、二度目はエラーが返ってきます。ローカル環境では問題なく成功します。

環境

windows10
apache2.4
python3.8
flask

ソースコード

python

1from flask import Flask,render_template 2import os 3 4app = Flask(__name__) 5 6@app.route("/") 7def sample(): 8 os.chdir("C:/Users/USERNAME/Documents/ディレクトリ名") 9 return render_template("sample.html") 10 11if __name__ == "__main__": 12 app.run(debug=True)

エラーメッセージ(apache)

apache

1[Thu Dec 31 07:34:43.863129 2020] [authz_core:error] [pid 16632:tid 1256] [client ::1:64153] AH01630: client denied by server configuration: C:/Users/USERNAME/Documents/ディレクトリ名/htdocs

httpd.conf

httpd

1 2Define SRVROOT "c:/Apache24" 3ServerRoot "${SRVROOT}" 4 5Listen 80 6Listen 1001 7Listen 2001 8Listen 3001 9Listen 4001 10Listen 5001 11 12LoadModule actions_module modules/mod_actions.so 13LoadModule alias_module modules/mod_alias.so 14LoadModule allowmethods_module modules/mod_allowmethods.so 15LoadModule asis_module modules/mod_asis.so 16LoadModule auth_basic_module modules/mod_auth_basic.so 17LoadModule authn_core_module modules/mod_authn_core.so 18LoadModule authn_file_module modules/mod_authn_file.so 19LoadModule authz_core_module modules/mod_authz_core.so 20LoadModule authz_groupfile_module modules/mod_authz_groupfile.so 21LoadModule authz_host_module modules/mod_authz_host.so 22LoadModule authz_user_module modules/mod_authz_user.so 23LoadModule autoindex_module modules/mod_autoindex.so 24LoadModule cgi_module modules/mod_cgi.so 25LoadModule dir_module modules/mod_dir.so 26LoadModule env_module modules/mod_env.so 27LoadModule include_module modules/mod_include.so 28LoadModule isapi_module modules/mod_isapi.so 29LoadModule log_config_module modules/mod_log_config.so 30LoadModule mime_module modules/mod_mime.so 31LoadModule negotiation_module modules/mod_negotiation.so 32LoadModule setenvif_module modules/mod_setenvif.so 33 34<IfModule unixd_module> 35User daemon 36Group daemon 37</IfModule> 38 39ServerAdmin admin@example.com 40 41ServerName localhost:80 42 43<Directory /> 44    AllowOverride none 45    Require all denied 46</Directory> 47 48DocumentRoot "${SRVROOT}/htdocs" 49<Directory "${SRVROOT}/htdocs"> 50    Options Indexes FollowSymLinks ExecCGI 51    AllowOverride None 52    Require all granted 53</Directory> 54 55<IfModule dir_module> 56    DirectoryIndex index.html 57</IfModule> 58 59<Files ".ht*"> 60    Require all denied 61</Files> 62 63ErrorLog "logs/error.log" 64 65LogLevel warn 66 67<IfModule log_config_module> 68    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined 69    LogFormat "%h %l %u %t \"%r\" %>s %b" common 70 71    <IfModule logio_module> 72      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio 73    </IfModule> 74 75    CustomLog "logs/access.log" common 76 77</IfModule> 78 79<IfModule alias_module> 80    ScriptAlias /cgi-bin/ "${SRVROOT}/cgi-bin/" 81</IfModule> 82 83<IfModule cgid_module> 84</IfModule> 85 86<Directory "${SRVROOT}/cgi-bin"> 87    AllowOverride None 88    Options None 89    Require all granted 90</Directory> 91 92<IfModule headers_module> 93    RequestHeader unset Proxy early 94</IfModule> 95 96<IfModule mime_module> 97    TypesConfig conf/mime.types 98    AddType application/x-compress .Z 99    AddType application/x-gzip .gz .tgz 100    AddHandler cgi-script .cgi .py 101</IfModule> 102 103<IfModule proxy_html_module> 104Include conf/extra/proxy-html.conf 105</IfModule> 106 107<IfModule ssl_module> 108SSLRandomSeed startup builtin 109SSLRandomSeed connect builtin 110</IfModule> 111 112LoadFile "c:/users/USERNAME/appdata/local/programs/python/python38/python38.dll" 113LoadModule wsgi_module "c:/users/USERNAME/appdata/local/programs/python/python38/lib/site-packages/mod_wsgi/server/mod_wsgi.cp38-win_amd64.pyd" 114WSGIPythonHome "c:/users/USERNAME/appdata/local/programs/python/python38" 115 116<VirtualHost *:1001> 117 DocumentRoot "htdocs/app/APP1" 118 WSGIScriptAlias / "htdocs/app/APP1/main.wsgi" 119 <Directory "htdocs/app/APP1"> 120 Require all granted 121 </Directory> 122</VirtualHost> 123 124<VirtualHost *:2001> 125 DocumentRoot "htdocs/app/APP2" 126 WSGIScriptAlias / "htdocs/app/APP2/main.wsgi" 127 <Directory "htdocs/app/APP2"> 128 <Files main.wsgi> 129 Require all granted 130 </Files> 131 </Directory> 132</VirtualHost> 133 134<VirtualHost *:3001> 135 DocumentRoot "htdocs/app/APP3" 136 WSGIScriptAlias / "htdocs/app/APP3/main.wsgi" 137 <Directory "htdocs/app/APP3"> 138 Require all granted 139 </Directory> 140</VirtualHost> 141 142<VirtualHost *:4001> 143 DocumentRoot "htdocs/app/APP4" 144 WSGIScriptAlias / "htdocs/app/APP4/main.wsgi" 145 WSGIApplicationGroup %{GLOBAL} 146 <Directory "htdocs/app/APP4"> 147 <Files main.wsgi> 148 Require all granted 149 </Files> 150 </Directory> 151</VirtualHost> 152 153<VirtualHost *:5001> 154    DocumentRoot "htdocs/app/sample" 155    WSGIScriptAlias / "htdocs/app/sample/main.wsgi" 156    <Directory "htdocs/app/sample"> 157      Require all granted 158    </Directory> 159</VirtualHost> 160

気になるのが、エラーメッセージで返ってくるパスの末尾にhtdocsが追加されていることです。

また、その際の画面表示は
Forbidden
You don't have permission to access this resource.
です。
サーバー上ではどのような動作が行われているのでしょうか。
アドバイスいただけると助かります。よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2020/12/31 00:08

C:/Users/USERNAME/Documents/ディレクトリ名 というパスがサーバーに存在しないのでは? また、サーバーの OS は Windows ですか?
gogotowel

2020/12/31 01:00

ありがとうございます。 パスは間違いなく存在します。 サーバーOSはwindows10です。 サーバー機でローカル環境も合わせて試しております。
A_kirisaki

2020/12/31 15:56

httpd.conf を見せていただけますか?
gogotowel

2020/12/31 23:05

ありがとうございます。 追記しました。 実際には複数のプログラムをVirtualHostで動作させてますが、こちらでは該当部分のみ記載しております。
A_kirisaki

2021/01/01 02:12

複数の……その VirtualHost 部分も追記していただけますか?念の為
gogotowel

2021/01/01 04:51

VirtualHost及び対応するListen部分も追記いたしました。 これで全ての内容となります。 どうぞよろしくお願いいたします。
guest

回答1

0

ベストアンサー

すみません、「一回だけ成功する」理由はわかりましたが「403 が返ってくる」まではつかめませんでした。とりあえず前者の報告まで。

まず Flask というのは Python の WSGI という決まりの上で動かされます。この仕組みを Apache でも動かせるようにしたのが mod_wsgi というモジュールになります。上でプロセス、スレッドを共有し Python コードが走ってサーバーとして動く構造となっています。

次に Apache は ServerRootDocumentRoot という概念を持ちます。ServerRoot + DocumentRoot のパスを基点に Web サーバーとして動きます。例えば上記の httpd.conf から抜き出すと

Apache

1Define SRVROOT "c:/Apache24" 2ServerRoot "${SRVROOT}" 3DocumentRoot "${SRVROOT}/htdocs" 4<Directory "${SRVROOT}/htdocs"> 5 Options Indexes FollowSymLinks ExecCGI 6 AllowOverride None 7 Require all granted 8</Directory>

c:/Apache24/htdocs を基点に Web サーバーとして配信します、という設定がなされています(上記設定で 80 番ポートにアクセスすると「It works!」というページが表示されるはずです)。

Apache の WSGI に関する設定部分を見ましょう。

Apache

1<VirtualHost *:5001> 2 DocumentRoot "htdocs/app/sample" 3 WSGIScriptAlias / "htdocs/app/sample/main.wsgi" 4 <Directory "htdocs/app/sample"> 5 Require all granted 6 </Directory> 7</VirtualHost>

この場合基点は c:/Apache24/htdocs/app/sample になります。そして WSGIScriptAlias の意味ですが、リクエストのパスが / の場合(http://localhost:5001/ でアクセスした場合)、サーバーの内部では DocumentRoot を基点として htdocs/app/sample/main.wsgi を呼び出すという意味になります。<Directory ... 以下はそのディレクトリへのアクセスを許可する設定です。

さて、一度目のリクエストが Apache にやってきます。すると Apache はリクエストの URL を見てどの処理を行うか決めます。http://localhost:5001/ にアクセスした場合、上記の main.wsgi が呼ばれます。すると中で os.chdir() が実行されます。そしてこの時、Apache の DocumentRoot も同時に変わってしまいます。つまり二回目にリクエストを送る時、DocumentRootC:/Users/USERNAME/Documents/ディレクトリ名 になっているのです。この状態で main.wsgi を呼び出そうとしても呼び出せないので失敗します。

なぜそうなるか

これは憶測なのですが、ワーカー(スレッドかプロセス)を Python と共有しているため作業ディレクトリを受け継いでいるのではないかと思われます。もし Apache の設定でワーカーを有効にすると例えば A と B というワーカーがあったとして A にアクセスした後 B にアクセスしても B はまだ成功します。その後どっちにアクセスしても失敗する、というような動きをするでしょう。

なぜ 403 になるのか

これはちょっと調べきれませんでした。ただ Windows の Documents 以下のディレクトリということで特殊な扱いを受けてて、 Apache の設定ファイルを探すと Require all denied となっているところがあるのかもしれません。

投稿2021/01/01 14:54

A_kirisaki

総合スコア2853

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gogotowel

2021/01/01 23:05

大変分かりやすい説明ありがとうございました。 それならos.chdir()はApache上では使用を控えるべきですね。プログラム側の基点がApacheの基点に切り替わったことで、エラーメッセージ内のパスの末尾にhtdocsが追加されていたのも納得です。 これですっきりと他の手段を検討できます…ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問