ファイル表示
ホーム
ホームページ
更新履歴
NOW!
チャット
ボイスチャット
ボイスメール
分身一覧
中継一覧
チャットメンバー

MSサポート情報検索
検索ページ
システム概要

パスワード変更
システム概要
ダウンロード

フォロー
一覧
WINTIS97

ツール、TIPS
Urlコンポーネント
Sessionモニタ
Excel作成
webinfo
きゃらメール
delold.vbs
rentoday.vbs
ASP TIPS
IRC伝言サービス
IRC計算サービス
プロファイル aspProfile
時間計測 TimeTool
MIMEマップ操作
電話番号11桁対応
ServerVariables
IPアドレス設定
Mediaモニタ
数式電卓
ファイル表示
CHOCOA URL紹介

お勧め
ソフトウェア
ハードウェア
リンク

WinNT WebRing
サイト一覧
前へ
次へ
ランダム
 
日本骨髄バンク  
PASSJ  
【楽天市場】ホビー・ペット・コレクション  
 
 
 

ファイルを表示する ASP ページです。
たとえば、

http://www.kawabata.com/view/view.asp?FILE=home1.jpg

とすると、hello.jpg ファイルを表示します。
ファイルを直接URL指定させず、なんからの条件処理をしたい場合や、
ファイルのアクセス数をリアルタイムにカウントしたい場合などに
利用できます。
また、このスクリプトでは、ファイルの最終更新日を利用して、
ファイルが更新されていない場合に、キャッシュが利用されるように
しています。

ファイル
view.asp
必要ファイル
Babaさんの開発されたBASP21.DLL が必要です。
Basp21.DLL の BinaryRead メソッドを利用しています。
使い方
view.asp を IIS のディレクトリに配置します。
view.asp の中の 3行目

  Const strBase = " D:\kawabata\wwwroot\webcam32\"  

を適切なディレクトリ名に変更します。
注意:このディレクトリ以下のファイルは、すべてアクセスできるようになります。
したがって、C:\ とすることは、危険です。

これで、設定は終了です。

http://server/view.asp?FILE=ファイル名

 と指定してください。
サブディレクトリを指定する場合は、

http://server/view.asp?FILE=パス/ファイル名

 と、スラッシュで区切ってください。

対応する拡張子
拡張子と、ContentType の組み合わせは、ContentTypeExt 関数で定義しています。
必要に応じて拡張してください。
ユーザー認証への対応
ユーザー認証した場合のみ、ファイルを表示したい場合は、
認証確認後、ResponseFile関数を呼び出すようにしてください。
たとえば、正しく認証している場合、Session("USERNAME") にユーザー名が
入っている場合には、

If Session("USERNAME") = "" Then
  Response.Write "ログオンしていません"
  Response.End
End If

If ResponseFile(strBase) > 0 Then
  Response.End
End If


などが、考えられます。
キャッシュ対応
このASPでは、HTTP/1.1で規定されたキャッシュ制御機能のうち、
HTTP ヘッダーで定義する Last-Modified と If-Modified-Since を
利用しています。

まず、view.asp は、ファイルを出力する場合、HTTP のレスポンス・ヘッダーに
Last-Modified として、ファイルの最終更新日付を返します。

例:
HTTP/1.1 200 OK
Server: Microsoft-IIS/4.0
Date: Tue, 29 Feb 2000 20:21:42 GMT
Last-Modified: Sat, 17 Jul 1999 22:12:34 GMT
Content-Type: image/jpeg
Cache-control: Private

この後、データが続く

クライアントのブラウザは、このURLに対して、もう一度、表示するときには、
Last-Modified の値を If-Modified-Since として、サーバーに渡します。

例:
GET http://localhost/test/view.asp?FILE=picf0004.jpg HTTP/1.0
Accept: */*
Accept-Language: ja
Accept-Encoding: gzip, deflate
If-Modified-Since: Sat, 17 Jul 1999 22:12:34 GMT
User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT)
Host: localhost
Proxy-Connection: Keep-Alive
Pragma: no-cache
Cookie: ASPSESSIONIDQGQQQHFU=JDFDKDPBFGADIILPANNOPELI

view.asp では、ファイルの最終更新日付と、If-Modified-Since の値を
比較して、更新されていれば、ファイルの内容を送信し、
更新されていなければ、次のように、更新されていないという
メッセージのみ返し、ファイルの内容は送信しません。

例:
HTTP/1.1 304 Not Modified
Server: Microsoft-IIS/4.0
Date: Tue, 29 Feb 2000 20:22:16 GMT
Content-Type: text/html
Cache-control: private

したがって、更新されていないファイルを繰り返しサーバーから
ダウンロードすることを防ぐことができます。
これによって、サーバーの負荷の軽減と、クライアントのレスポンスを
向上、回線負荷の軽減を行うことができます。
Proxy キャッシュ対応
このview.asp結果は、それぞれのクライアントには、保存されますが、
Proxy Server のキャッシュには、保存されません。
それは、次のように指定しているためです。

Response.CacheControl = "Private"

Proxy Server に保存してもよい場合は、

Response.CacheControl = "Public"

としてください。
ただし、このようにした場合、セキュリティ認証をしたとしても、
キャッシュ側を参照される可能性があります。
データベースへの応用
今回利用した、Last-Modified と If-Modified-Since は、データベースのページを
ASP から参照する場合にも、利用することができます。
たとえば、特定のレコードの更新日付をレコードのフィールドの値として保存しているので
あれば、この値を Last-Modified として返すことにより、
特定のレコードを WWW 上に表示した結果を効率よく、クライアントに保存し、
また、データベースへの処理を軽減することができます。

画像などのファイルをデータベースに保存している場合にも、利用できます。

ETagとIf-None-Match対応
HTTP/1.1では、Last-Modified と If-Modified-Since と同様な機能として、
ETag と、If-None-Match というヘッダーがあります。
ETag は、コンテンツのバージョンなどをあらわす値です。
サーバーが ETag を返した場合、クライアントは、次回のアクセスから If-None-Match を
つけて、サーバーにアクセスします。
したがって、データベースなどでは、レコードの更新回数などをETag として
送信しておくことにより、より簡単にレコードの更新評価が可能となります。
ファイルが多い場合

更に、活用方法として、ファイル数が1000ファイルを超える場合にも、
利用できます。
たとえば、ひとつのディレクトリに1000以上のファイルを置いておくと、
なにかと管理が難しくなります。たとえば、エクスプローラでフォルダを
開くにも、かなりの時間がかかります。

そこで、ファイルを999個づつ、別々のディレクトリに置いておきます。
ユーザーからは、
http://server/view.asp?FILE=AAAxxx222.jpg
としてアクセスされた場合に、実際のディスクの
D:\AAA\xxx\222.jpg
を参照することができます。

view.asp のチョットした修正で対応できますね。

動作確認
動作確認をするには、HTTPパケットを直接見る必要があります。
手軽に利用できるソフトとしては、秀シリーズの「横取り丸」と「InetSpy」の組み合わせがあります。
小さくて、扱いやすいソフトウェアですので、ぜひお試しください。
http://hide.maruo.co.jp/
このページから、「ソフトウェア」を選択すると、ダウンロードできます。
考察
今回は、JPG ファイルへのアクセスに、認証をかけたいという話から始まりました。
ISAPI で開発することも可能でした。
しかし、BASIC認証やNTLM認証などを使わず、SQLServer上のユーザーテーブルを
利用して認証しているとのことでしたので、ASP で実現しました。
また、ASP で Last-Modified が利用できるかどうかのテストも兼ねています。
お試しいただければと思います。

PDFの場合は、バイトサービング機能により、ページ単位にアクセスされますので、
また別途検討が必要です。

ソース
<%
  '--- view.asp
  Const strBase = "D:\kawabata\wwwroot\webcam32\"

  If ResponseFile(strBase) > 0 Then
    Response.End
  End If
%>
<html>
<head><title>ファイル表示</title></head>
<body>
  ファイル名が指定されていません<BR>
  <% = FormatDateHTTP(Now) %>
</body>
</html>
<%
'-----------------------------------------------------------

'--- ファイルを出力する
Function ResponseFile(strBase)
  '--- 戻り値の初期化
  ResponseFile = 0

  '--- 変数宣言
  Dim strFile
  Dim strPath
  Dim strIfModifiedSince
  Dim objFileSystem
  Dim objFile

  '--- オブジェクト宣言
  Set objFileSystem = Server.CreateObject("Scripting.FileSystemObject")

  '--- Request変数
  strFile = Replace(Trim(Request("File")), "/", "\")
  strIfModifiedSince = Trim(Request.ServerVariables("HTTP_IF_MODIFIED_SINCE"))
  If strFile = "" Then 
    Exit Function
  End If

  '--- ファイルオブジェクト取得
  strPath = strBase & strFile
  On Error Resume Next
  Set objFile = objFileSystem.GetFile(strPath)
  If Err <> 0 Then
    Response.Status = "404 Not Found"
    ResponseFile = 404
    Exit Function
  End If

  '--- 更新日付確認
  dtmLastModifed = objFile.DateLastModified
  strLastModifed = FormatDateHTTP(dtmLastModifed)
  If strIfModifiedSince <> "" Then
    If StrComp(strLastModifed, strIfModifiedSince, vbTextCompare) = 0 Then
      '--- 未修正
      Response.Status = "304 Not Modified"
      ResponseFile = 304
      Exit Function
    End If
  End If

  '--- キャッシュ設定
  Response.CacheControl = "Private"

  '--- 更新日付出力
  Response.AddHeader "Last-Modified", strLastModifed

  '--- ContentType 出力
  strExt = LCase(objFileSystem.GetExtensionName(strPath))
  Response.ContentType = ContentTypeExt(strExt)

  '--- ファイルの出力
  Set objBasp = Server.CreateObject("Basp21")
  If Not IsObject(objBasp) Then
    Response.End
  End If
  baryContent = objBasp.BinaryRead(strPath)
  Response.BinaryWrite baryContent

  '--- 終了
  ResponseFile = 200
End Function

'--- 拡張子からContentTypeを得る
Function ContentTypeExt(strExt)
  Select Case LCase(strExt)
  Case "jfif", "jpe", "jpeg", "jpg"
    ContentTypeExt = "image/jpeg"
  Case "gif"
    ContentTypeExt = "image/gif"
  Case "png"
    ContentTypeExt = "image/png"
  Case "tif"
    ContentTypeExt = "image/tif"
  Case "pdf"
    ContentTypeExt = "application/pdf"
  Case Else
    ContentTypeExt = "application/octet-stream"
  End Select
End Function

'--- HTTP/1.1 の日付形式(GMT) を返す
Function FormatDateHTTP(ByVal dtmValue)

  FormatDateHTTP = ""
  If Not IsDate(dtmValue) Then
    Exit Function
  End If

  '--- GMT = JST - 9
  dtmValue = DateAdd("h", 9, dtmValue)
  '--- Format
  FormatDateHTTP = WeekdayNameE(Weekday(dtmValue)) & ", " _
    & FormatN(Day(dtmValue), 2) & " " _
    & MonthNameE(Month(dtmValue)) & " " _
    & Year(dtmValue) & " " _
    & FormatN(Hour(dtmValue), 2) & ":" _
    & FormatN(Minute(dtmValue), 2) & ":" _
    & FormatN(Second(dtmValue), 2) & " GMT"
End Function

'--- 数値を 001 形式と 0 で桁あわせする
Function FormatN(lngValue, lngSize)
  FormatN = Right(String(lngSize, "0") & CStr(lngValue), lngSize)
End Function

'--- 英語の曜日名を短縮形で返す
Function WeekdayNameE(lngWeekday)
  Dim aryWeekdayName

  WeekdayNameE = ""
  aryWeekdayName = Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
  If lngWeekday < 1 Or lngWeekday > 7 Then
    Exit Function
  End If

  WeekdayNameE = aryWeekdayName(lngWeekday - 1)
End Function

'--- 英語の月名称を短縮形で返す
Function MonthNameE(lngMonth)
  Dim aryMonthName

  MonthNameE = ""
  aryMonthName = Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec")
  If lngMonth < 1 Or lngMonth > 12 Then
    Exit Function
  End If

  MonthNameE = aryMonthName(lngMonth - 1)
End Function
%>
作成:河端
Hotmail,MSN Messanger:YoshihiroKawabata
参照:
管理:/view/default.asp
   管理ツール