質問をすることでしか得られない、回答やアドバイスがある。

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

ただいまの
回答率

87.94%

さくらのレンタルサーバーでcgiを用いた .pyがInternal Server Errorになる

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,015

score 14

環境

本番環境
Python 3.6.9
Server version: Apache/2.4.29 (Ubuntu)

ローカル環境
Python 3.6.6
MacOS

発生している問題

ローカル環境では全て動作することを確認済みで、本番環境であるさくらのレンタルサーバーで実行することを試みました。本番環境ではcgi-bin/index.pyは正常に表示され、そこからログインするためのcgi-bin/login_form.pyやアカウントを作成するためのcgi-bin/create_account.pyには正常にページ遷移できます。しかし、cgi-bin/login_form.pycgi-bin/create_account.pyのフォームから値を受け取ってそれをdbにアクセスしたり、その結果を表示するためのcgi-bin/login.pycgi-bin/done.pyに遷移しようとするとInternal Server Errorが表示されます。それ以外にもいくつか.pyファイルがありますが、それら全てにアクセスしてもInternal Server Errorが表示されてしまいます。apacheのエラーログのメッセージはResponse header name '<!--' contains invalid characters, aborting request, refererです。

該当部分のソースコード

基本的な構造は同じだと思うので、cgi-bin/login_form.pyからcgi-bin/login.pyの一部を抜粋して貼ります。
まず、login_form.pyです

#!/usr/bin/env python3
#encoding:UTF-8
import cgi
import cgitb
import textwrap
import io,sys
# UnicodeEncodeErrorを防ぐ
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
cgitb.enable()

print("Content-Type: text/html; charset=UTF-8\n\n")
html ='''
<!DOCTYPE html>
<html lang = "ja">
<head>
<title>hogehoge</title>
</head>
  <body>
    <h1>hoge</h1>
    <form
      action = "./login.py"
      method = "post"
      >
    <h2>user id : <input type = "text" name = "user_id" id='name'></h2>
    <h2>pssword : <input type = "password" name = "password" minlength='8' id='pass'></h2>
    <input type = "submit" value = "sign-in">
  </body>
</html>
'''.format().strip()
print(html)

次に、login.pyです

import cgi
import cgitb
import sqlite3
import textwrap
from http import cookies
import hashlib
import io,sys
# UnicodeEncodeErrorを防ぐ
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
cgitb.enable()
conn = sqlite3.connect('./hogehoge/hoge.db')
c = conn.cursor()
form = cgi.FieldStorage()
user_id = form['user_id'].value

# クッキーを生成しuser_id を遷移先のページに渡す
print("Set-Cookie: user="+ user_id)
print("Content-Type: text/html; charset=UTF-8\n\n")

html = textwrap.dedent('''
 <!DOCTYPE html>
<html lang = "ja">
<head>
<title>hoge</title>
</head>
    <body>
      {0}
    </body>
</html>
''').format(get(c, form)).strip() #get関数ではフォームの値からユーザーのパスワードが正しいかなどを検証して、その結果を表示しようとしています。
print(html)

エラーメッセージ

上記のファイルから画面遷移した際にブラウザ上にはInternal Server Error表示されます。
apacheのエラーログを確認したところ、

AH02429: Response header name '<!--' contains invalid characters, aborting request, referer: http://****/username/ディレクトリ名/cgi-bin/login_form.py


というように表示されています。

確認したこと・試したこと

  • ls -al でcgi-binのファイルに実行権限があることは確認しました。
  • 似たような質問への回答でprint("Content-Type: text/html\r\n\r\n")としてみてはとあったので試しましたが、結果は変わりませんでした。
  • .htaccess にはAddHandler cgi-script .pyを追加しましたが、結果は変わりませんでした。
  • ファイル名を .pyから .cgiに変更してみましたが、結果は変わりませんでした。

以上です。原因の究明に少し行き詰まってしまったので、悪さをしていそうな部分や他に試した方がいいことなどありましたら是非ご教授ください。よろしくお願いします。

追記

上に記載されているlogin_form.pyも表示できていますが、他にはindex.pyも表示されるので、こちらを追記しておきます。

#!/usr/bin/env python3
#encoding:UTF-8

def check_cookie(cookie):
    if 'user' in cookie:
        str = '''
        <h2>Welcome {0}!</h2>
        <a href='./hogehoge.py'>hogehoge</a>  
        '''.format(cookie['user'].value)
    else:
        str = '''
        <a href='./login_form.py'>Sign In!</a>
        <a href='./create_account.py'>Sign Up!</a>
        '''
    return str


import cgi
import cgitb
import textwrap
from http import cookies
import os
import io,sys
# UnicodeEncodeErrorを防ぐ
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
# クッキーの取得
cookie = cookies.SimpleCookie(os.environ.get("HTTP_COOKIE",""))

cgitb.enable()
# クッキーが生成されていたらuserとして遷移先のページでもクッキーを渡し続ける処理
if 'user' in cookie:
    user = cookie['user'].value
    print("Set-Cookie: user="+ user)
print("Content-Type: text/html; charset=UTF-8\n\n")

html = '''
<!DOCTYPE html>
<html lang = "ja">
<head>
<title>hogehoge</title>
</head>
  <body>
    <h1>hoge</h1>
    {get}
  </body>
</html>
'''.format(get = check_cookie(cookie)).strip()

print(html)
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • dodox86

    2020/06/07 23:49

    './hogehoge/hoge.db' を絶対PATH指定にすると状況が変わるかもしれませんね。ご提示のコード全部を読んでいる訳でないので、半ば当てずっぽうですが。

    キャンセル

  • Noisman

    2020/06/08 01:05

    dodox86 さん
    アドバイスありがとうございます。
    どうやらデータベースのパスの指定が間違っていたようで、cgitb.enable()の出力が邪魔していたようですね。データベースを正しいパスで指定して実行したら無事解決できました!ありがとうございます

    キャンセル

  • dodox86

    2020/06/08 01:12

    解決できてよかったです。原因と対応を添えて、自己解決/回答を投稿して質問を閉じていただければと思います。よろしくお願いします。

    キャンセル

回答 1

check解決した方法

0

データベースへのパスが間違っていたため例外としてcgitb.enable()の内容が表示された際にInternal Server Errorとなってしまったようです。
正しいデータベースのパスを指定することで解決しました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 87.94%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る