C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.88724 の関連記事表示

<< 0 | 1 >>
■88724  文字化けする画像ファイルヘッダー
□投稿者/ ひょっとこ -(2018/09/22(Sat) 10:12:01)

    分類:[.NET 全般] 



    HTMLファイルを作成し、

    <!DOCTYPE html>
    <img src="http://cms1.ishikawa-c.ed.jp/~shough/NC2/htdocs/?action=common_download_main&amp;upload_id=4537" alt="" />
    </html>

    と書きます。
    作成したHTMLファイルをIEで開き、画像の上で右クリックメニューから
    画像の保存を行います。
    するとファイル名は
    DSC_0063 - コピー北國新聞社社長賞.JPG
    となります。

    このファイル名はHTMLファイル内には記述していないので
    恐らく、ファイルヘッダーから取得したのだと思います。

    どこのサイトで調べたのかは忘れましたが、
    以下のコードでヘッダーからファイル名を取得することができます。


    これで取得するとファイル名は

    "DSC_0063 - &atilde;" & ChrW(130) & "&sup3;&atilde;" & ChrW(131) & ChrW(148) & "&atilde;" & ChrW(131) & "&frac14;&aring;" & ChrW(140) & ChrW(151) & "&aring;" & ChrW(156) & ChrW(139) & "&aelig;" & ChrW(150) & "°&egrave;" & ChrW(129) & ChrW(158) & "&ccedil;&curren;&frac34;&ccedil;&curren;&frac34;&eacute;" & ChrW(149) & "&middot;&egrave;&sup3;" & ChrW(158) & ".JPG"

    になってしまいます。
    半角英数字はうまく取得できているのですが、
    全角文字のところが全て文字化けしてしまってうまく取得することができません。

    どのようにすれば、うまく取得できますか?


    Sub Main()


    Dim FileName As String = AcquireFileNameFromHeader(HttpUtility.HtmlDecode("http://cms1.ishikawa-c.ed.jp/~shough/NC2/htdocs/?action=common_download_main&amp;upload_id=4537"))


    End Sub



    Function AcquireFileNameFromHeader(URL$) As String


    Dim req As HttpWebRequest = CType(WebRequest.Create(URL), HttpWebRequest)

    Dim fileName As String = ""


    Dim res As HttpWebResponse = CType(req.GetResponse(), HttpWebResponse)

    Dim dispos As String = res.Headers("Content-Disposition")

    If Not String.IsNullOrEmpty(dispos) Then

    Dim re As New Regex(
    "filename\s*=\s* " &
    "(?: " &
    " ""(?<filename>[^""]*)"" " &
    " | " &
    " (?<filename>[^;]*) " &
    ") " _
    , RegexOptions.IgnoreCase _
    Or RegexOptions.IgnorePatternWhitespace)

    Dim m As Match = re.Match(dispos)
    If m.Success Then
    fileName = m.Groups("filename").Value
    End If
    End If



    If Not (res Is Nothing) Then
    res.Close()
    End If


    Return fileName

    End Function


親記事 /過去ログ152より / 関連記事表示
削除チェック/

■88725  Re[1]: 文字化けする画像ファイルヘッダー
□投稿者/ WebSurfer -(2018/09/22(Sat) 10:27:41)
    No88724 (ひょっとこ さん) に返信

    > このファイル名はHTMLファイル内には記述していないので
    > 恐らく、ファイルヘッダーから取得したのだと思います。

    要求・応答ヘッダ―の中身を見るのが目的で、それを取得するための方法は問わないというこ
    とであれば Fiddler を使うのがお勧めです。

    Fiddler のお勧め
    http://surferonwww.info/BlogEngine/post/2011/05/25/Recommendation-of-Fiddler.aspx

    IE なら F12 開発者ツールを使っても取得できます・・・が、使いにくいので Fiddler をお
    勧めします。
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88726  Re[2]: 文字化けする画像ファイルヘッダー
□投稿者/ ひょっとこ -(2018/09/22(Sat) 10:40:57)
    VB.NET上で取得する必要があるので
    他のソフトウェアは使いたくないのですが・・・・
    よろしくお願いいたします。
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88727  Re[3]: 文字化けする画像ファイルヘッダー
□投稿者/ WebSurfer -(2018/09/22(Sat) 10:59:05)
    No88726 (ひょっとこ さん) に返信
    > VB.NET上で取得する必要があるので
    > 他のソフトウェアは使いたくないのですが・・・・
    > よろしくお願いいたします。

    そうですか・・・

    でも、やっぱり Fiddler を使ってみることをお勧めします。それで応答ヘッダ―を見ると文字化けの
    原因が分からるかも。最低でも何らかのヒントは得られるはずです。
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88731  Re[1]: 文字化けする画像ファイルヘッダー
□投稿者/ 魔界の仮面弁士 -(2018/09/22(Sat) 14:29:16)
    No88724 (ひょっとこ さん) に返信
    > どこのサイトで調べたのかは忘れましたが、
    > 以下のコードでヘッダーからファイル名を取得することができます。
    
    恐らく下記では無いでしょうか。見覚えはありますか?
    http://www.atmarkit.co.jp/fdotnet/dotnettips/618downnoname/downnoname.html
    
    上記には URL$ という名の引数は出てこないので、自前で書き直した記憶が無ければ、
    上記を元に二次加工されたソースだったのかも知れませんが。
    
    
    > Dim req As HttpWebRequest = CType(WebRequest.Create(URL), HttpWebRequest)
    今回のように、ヘッダー情報を読み取ることだけを目的としているのであれば、
    HTTP GET のままリクエストするのではなく、
     req.Method = System.Net.Http.HttpMethod.Head.Method
     'req.Method = "HEAD"
    のように HTTP HEAD メソッドに変更してリクエストするべきかと思います。
    
    
    > DSC_0063 - コピー北國新聞社社長賞.JPG
    > このファイル名はHTMLファイル内には記述していないので
    > 恐らく、ファイルヘッダーから取得したのだと思います。
    
    参照されているのは、ファイルヘッダーではなく、HTTP 応答ヘッダーですね。
    
    http://cms1.ishikawa-c.ed.jp/~shough/NC2/htdocs/?action=common_download_main&upload_id=4537
    の画像では Exif 情報も削除されているため、ファイルヘッダーからは取得できないはず。
    
    
    該当の URL にアクセスすると、Web サーバーから下記の応答が返されることを確認しました。(一部抜粋)
    
    HTTP/1.1 200 OK
    Date: Sat, 22 Sep 2018 01:46:42 GMT
    Server: Apache/2.2.15 (CentOS)
    Content-disposition: inline; filename="DSC_0063 - コピー北國新聞社社長賞.JPG"
    Content-Length: 85599
    Connection: close
    Content-Type: image/jpeg
    
    
    この時、filename= の後続のカナ漢字部分が UTF-8 エンコーディングになっていたので、
    これが文字化けの原因ですね。
    
    そしてこれは、Web サーバー側の処理に問題があるように思います。
    
    HTTP ヘッダでの利用が許可されているのは、現時点では ISO-8859-1 のみですので、
    UTF-8 でエンコードされた文字列が返されるのは、本来は NG のはずです。
    
    2011年6月に RFC 6266 で定められるまでは、ファイル名に使われる非 ASCII 文字を
    Content-Disposition: にどのように組み込むかが明確に定義されておらず、
    各ブラウザーで解釈が異なっていたのですけれど、それは昔の話。
    
    現在では、日本語ファイル名なら RFC 6266 / RFC 5987 に従って、filename= ではなく filename*= を用いた
    Content-disposition: inline; filename*=utf-8'ja-jp'DSC_0063%20-%20%E3%82%B3%E3%83%94%E3%83%BC%E5%8C%97%E5%9C%8B%E6%96%B0%E8%81%9E%E7%A4%BE%E7%A4%BE%E9%95%B7%E8%B3%9E.JPG
    などの応答を Web サーバーが返却するのが正しい手順であろうかと思います。
    (ブラウザーによっては、"%20" の部分が " " にデコードされずに残る事もあるようですが)
    
    
    もしも仮に、上記のヘッダーで返却されていたのだとしたら、受信した文字列を
    下記の Uri.UnescapeDataString などでデコードすることで、正しく取得できるようになる見込みです。
    https://dobon.net/vb/dotnet/internet/urlencode.html
    
    ただしサーバーの実装が正しかったとしても、filename*= で utf-8 以外が指定されていた場合は、
    HttpUtility.UrlDecodeToBytes(String, Encoding) してから
    Encoding.Unicode.GetString( Byte() ) で復元する必要がありますし、
    そもそも No88724 の正規表現のままでは不足なので、いずれにしてももう少し手直しは必要です。
    
    
    
    閑話休題。
    
    話をまとめると、文字化けの原因は、サーバー側がファイル名 UTF-8 で返しているからであり、
    それを取得するための機能は、WebRequest クラスには存在しないという結論になります。
    
    WebRequest クラスには、ContentEncoding ならありますが、
    HeaderEncoding プロパティはありませんので…。
    
    
    代替手段を考えてみたのですが、今のところは、サーバーと会話する処理を
    自前で書くぐらいしか思い当たりませんでした。
    
    以下は、リダイレクトやエラー処理、SSL 対応、プロキシ指定等は考慮せず、
    あくまでも今回の URL に限定させた最低限の手抜き実装ですが、一応参考までに。
    
    
    'Imports System
    'Imports System.IO
    'Imports System.Net
    'Imports System.Net.Sockets
    'Imports System.Text
    'Imports System.Text.RegularExpressions
    
    Function AcquireFileNameFromUTF8Header(url As String) As String
        Dim headers As String()
    
        Dim u As New Uri(url)
        Using client As New TcpClient()
            client.Connect(u.Host, u.Port)
            Using stm As NetworkStream = client.GetStream()
                Dim wrt As New StreamWriter(stm)
                wrt.WriteLine("HEAD " & u.ToString() & " HTTP/1.1")
                wrt.WriteLine("Host: " & u.Host)
                wrt.WriteLine("Connection: close")
                wrt.WriteLine("")
                wrt.WriteLine("")
                wrt.WriteLine("")
                wrt.Flush()
    
                'UTF-8 で喋るサイトのために、無理矢理 UTF-8 でデコードしています。
                Dim rdr As New StreamReader(stm, Encoding.UTF8)
                headers = rdr.ReadToEnd().Split(New String() {vbCrLf}, StringSplitOptions.RemoveEmptyEntries)
            End Using
        End Using
    
        Dim cd = headers.FirstOrDefault(Function(h) h.ToLowerInvariant().StartsWith("content-disposition:"))
        If Not String.IsNullOrWhiteSpace(cd) Then
            'ここの正規表現は、元の正規表現のままで、特に弄っていません。
            Dim re As New Regex( _
                      "filename\s*=\s*           " & _
                      "(?:                       " & _
                      "  ""(?<filename>[^""]*)"" " & _
                      "  |                       " & _
                      "  (?<filename>[^;]*)      " & _
                      ")                         " _
                      , RegexOptions.IgnoreCase _
                  Or RegexOptions.IgnorePatternWhitespace)
    
            Dim m As Match = re.Match(cd)
            If m.Success Then
                Return m.Groups("filename").Value
            End If
        End If
        Return String.Empty
    End Function
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88730  Re[3]: 文字化けする画像ファイルヘッダー
□投稿者/ WebSurfer -(2018/09/22(Sat) 14:12:21)
    No88726 (ひょっとこ さん) に返信

    何故 Fiddler で見るように言ったのか理解されていないようなので追加情報を書いておきます。

    応答ヘッダの Content-Disposition の filename にファイル名が設定されていると思いますが、
    IE の場合「DSC_0063 - コピー北國新聞社社長賞.JPG」のような ASCII 文字でない日本語をそ
    のまま filename に設定すると文字化けするはずです。

    それを回避するため「コピー北國新聞社社長賞」の部分はパーセントエンコーディングしている
    と思います。

    さらに、RFC 6266 に準拠した設定がされているかもしれません。その場合 filename は以下の
    ようになります。

    filename*=utf-8''DSC_0063 - %e3%82%b3%e3%83%94%e3%83%bc%e5%8c%97%e5%9c%8b%e6%96%b0%e8%81%9e%e7%a4%be%e7%a4%be%e9%95%b7%e8%b3%9e.JPG

    HttpWebResponse はデコードしてくれません。res.Headers("Content-Disposition") で取得する
    とそのまま出てきます。

    質問者さんのコースで上記のことが当てはまるのかは分かりませんが、何にせよ、Fiddler で直接
    応答ヘッダーを見てそういうところを調べないと暗中模索で解決になかなかたどり着けません。
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88733  Re[4]: 文字化けする画像ファイルヘッダー
□投稿者/ 魔界の仮面弁士 -(2018/09/22(Sat) 15:00:12)
    No88730 (WebSurfer さん) に返信
    > さらに、RFC 6266 に準拠した設定がされているかもしれません。その場合 filename は以下の
    > ようになります。
    > filename*=utf-8''DSC_0063 - %e3%82%b3%e3%83%94%e3%83%bc%e5%8c%97%e5%9c%8b%e6%96%b0%e8%81%9e%e7%a4%be%e7%a4%be%e9%95%b7%e8%b3%9e.JPG
    
    仕様上は " - " ではなく "%20-%20" だと思っていました。
    
    意図的に " " を使うケースがあることは理解していますが、
    RFC 5987 の Section 3.2.1.を見る限りでは、半角空白は
    pct-encoded ではなく attr-char のようですし、
    RFC 6266 の Section 5 でも、下記のように %20 が使われていたので。
    
      Content-Disposition: attachment;
                           filename*= UTF-8''%e2%82%ac%20rates
    
      Content-Disposition: attachment;
                           filename="EURO rates";
                           filename*=utf-8''%e2%82%ac%20rates
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88735  Re[5]: 文字化けする画像ファイルヘッダー
□投稿者/ WebSurfer -(2018/09/22(Sat) 15:12:15)
    No88733 (魔界の仮面弁士 さん) に返信

    > 仕様上は " - " ではなく "%20-%20" だと思っていました。

    inline でそれだと、IE では表示された画像を右クリックして保存する際に付けられる名前に
    そのまま "%20-%20" が出てきてしまいます。

    ちなみに Firefox では " - " とすると DSC_0063.jpg になってしまいます。"%20-%20" は
    期待通り空白になります。

    要するにブラウザ依存のようです。質問者さんは IE とのことですので(ちょっと怪しいで
    すが) " - " と書いておきました。

    なお、attachment であれば "%20-%20" として一時ファイルに保存される名前は、IE, Chrome,
    Firefox いずれも " - " になるはずです。
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88740  Re[6]: 文字化けする画像ファイルヘッダー
□投稿者/ 魔界の仮面弁士 -(2018/09/22(Sat) 18:49:52)
    No88734 (WebSurfer さん) に返信
    >> 該当の URL にアクセスすると、Web サーバーから下記の応答が返されることを確認しました。(一部抜粋)
    > 使ったブラウザは何ですか? IE では文字化けするはずなのですか? Chrome を使ったとか?

    いえ。Port 80 に対して、最低限のリクエストを投げただけですね。
    User-Agent や Accept-Language 等は特に送出しませんでした。

    最初の質問のコードで使っている WebRequest.Create(URL) においては、
    HttpWebRequest.UserAgent の初期値が Nothing だったはずなので、
    それに合わせて、UA を付与せずに送出してみたということです。

    WebBrowser コントロールを使うような場合であれば、IE の通信内容との差異を
    チェックしたりもするのですが、今回はどちらかというと、
    RFC 仕様を確認する方に注力していました。


    一応、Edge 42 / Chrome 69 / Internet Explorer 11 において、
    ブラウザー上から「名前を付けて保存」を行い、それらすべてが
    文字化けせずに "DSC_0063 - コピー北國新聞社社長賞.JPG" という
    ファイル名を提案してくることと、その時の Content-disposition が
    filename*= 無しの filename= だけという事は確認していましたが、
    ブラウザーへの応答時のエンコードまでは気にしていませんでした。
    (ブラウザー上で処理したい訳では無かったので)



    > 画像を右クリックして名前を付けて保存しようとすると、
    > DSC_0063 - ・スR・スs・ス[・スk・ス・ス・スV・ス・ス・スミ社抵ソス・ス・ス.JPG
    > となります。

    それはおそらく、Fiddler を使ったことによるトラブルですね。

    試しに、その化けてしまう画像が表示された状態のまま、
    Fiddler の Capture Traffice を一時的にオフにした状態で、
    IE 上で [Ctrl]+[F5] で強制リロードしてみてください。今度は正しく、
    『DSC_0063 - コピー北國新聞社社長賞.JPG』で保存できる状態になると思います。



    > ちなみに Chrome は以下のようになります。文字化けはしません。

    先ほど追試してみたところ、"コピー" というファイル名は、
    Internet Explorer 11 は、81-45,BD-52,81-45 (Shift_JIS 相当)
    Edge 42 & Chrome 69 は、E3-82-B3,E3-83-94,E3-83-BC (UTF-8 相当)
    で返却されてきました。

    IE11 に対しても UTF-8 で返していると思い込んでいましたが、
    昔も今も、対 IE 向けには Shift_JIS 前提として処理されるのですね…。


    また、最初の質問にあったコードで、req.UserAgent を書き換えてみたところ、
    Content-Disposition の返却結果が上記のように変わることを確認しました。

    どうやら今回のサーバーは、User-Agent をチェックした上で
    応答を変える仕組みになっているとみて間違いなさそうです。



    No88737 (魔界の仮面弁士) に追記
    > たとえば、最近の Internet Explorer では、UTF-8 なバイナリを解釈できますが、
    > 古いバージョンの IE では、Shift_JIS 相当のバイナリとして解釈される事もあります。

    ということで、上記は私の勘違いでした。
    Internet Explorer 11 になっても、やはり Shift_JIS で解釈されるようですし、
    UTF-8 エンコードな filname=〜 を解釈することはできないようです。
    (filename=〜 ではなく、filename*=utf8''〜 であれば OK)



    No88735 (WebSurfer さん) に返信
    >>仕様上は " - " ではなく "%20-%20" だと思っていました。
    > inline でそれだと、IE では表示された画像を右クリックして保存する際に付けられる名前に
    > そのまま "%20-%20" が出てきてしまいます。

    そうですね。そしてそれゆえに、現実的な実装として
    >> 意図的に " " を使うケースがあることは理解していますが、
    としているケースが少なからず存在していることは、自分も把握しているのですが、
    それが RFC 仕様として許容されているものであるかどうかをご存知でしょうか、という意図です。
    (各社のブラウザー仕様ではなく、HTTP Response の仕様という意味で)


    > ちなみに Firefox では " - " とすると DSC_0063.jpg になってしまいます。"%20-%20" は
    > 期待通り空白になります。
    なるほど。ありがとうございます。
    Firefox 62 は検証したことが無かったので助かりました。

    RFC 仕様がどうであれ、現時点におけるサーバー側の実装としては、
    未だに UA チェック(主に対 IE 向け)を行うべきなようですね。


    > なお、attachment であれば "%20-%20" として一時ファイルに保存される名前は、IE, Chrome,
    > Firefox いずれも " - " になるはずです。
    参考になります。
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88742  Re[7]: 文字化けする画像ファイルヘッダー
□投稿者/ WebSurfer -(2018/09/22(Sat) 19:16:05)
    No88740 (魔界の仮面弁士 さん) に返信

    >> 画像を右クリックして名前を付けて保存しようとすると、
    >> DSC_0063 - ・スR・スs・ス[・スk・ス・ス・スV・ス・ス・スミ社抵ソス・ス・ス.JPG
    >> となります。

    > それはおそらく、Fiddler を使ったことによるトラブルですね。

    ご指摘の通りでした。混乱させてしまいすみません。


    > どうやら今回のサーバーは、User-Agent をチェックした上で
    > 応答を変える仕組みになっているとみて間違いなさそうです。

    これもご指摘の通りのようです。IE と Chrome を使って結果が違うというところで
    気づくべきでした。
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88749  Re[5]: 文字化けする画像ファイルヘッダー
□投稿者/ 魔界の仮面弁士 -(2018/09/23(Sun) 13:29:11)
    No88733 (魔界の仮面弁士) に追記
    >>さらに、RFC 6266 に準拠した設定がされているかもしれません。その場合 filename は以下の
    >>ようになります。
    >>filename*=utf-8''DSC_0063 - %e3%82%b3%e3%83%94%e3%83%bc%e5%8c%97%e5%9c%8b%e6%96%b0%e8%81%9e%e7%a4%be%e7%a4%be%e9%95%b7%e8%b3%9e.JPG
    > 仕様上は " - " ではなく "%20-%20" だと思っていました。
    
    .NET Framework 4.5 以降 (あるいは .NET Standard 1.1 以降) で追加されている
    System.Net.Http.Headers.ContentDispositionHeaderValue クラスを使うことで、
    Content-Disposition ヘッダーを簡単に処理することができました。
    
    
    しかしながら、RFC 6266 / RFC 5987 に従った、正しいヘッダー記述が求められるようで、
    filename*= で空白が "%20" になっていない場合や、
    filename= の後に漢字等が含まれていた場合には、解析エラーとなります。
    
    
    Dim head As System.Net.Http.Headers.ContentDispositionHeaderValue
    
    'これは成功する
    Dim value1 As String = "inline; filename*=utf-8''DSC_0063%20-%20%e3%82%b3%e3%83%94%e3%83%bc%e5%8c%97%e5%9c%8b%e6%96%b0%e8%81%9e%e7%a4%be%e7%a4%be%e9%95%b7%e8%b3%9e.JPG"
    head = System.Net.Http.Headers.ContentDispositionHeaderValue.Parse(value1)
    Console.WriteLine(head.FileNameStar)    '『DSC_0063 - コピー北國新聞社社長賞.JPG』
    Console.WriteLine()
    
    'これは解析エラーになる(System.FormatException)
    Dim value2 As String = "inline; filename*=utf-8''DSC_0063 - %e3%82%b3%e3%83%94%e3%83%bc%e5%8c%97%e5%9c%8b%e6%96%b0%e8%81%9e%e7%a4%be%e7%a4%be%e9%95%b7%e8%b3%9e.JPG"
    'head = System.Net.Http.Headers.ContentDispositionHeaderValue.Parse(value2)
    'Console.WriteLine(head.FileNameStar)
    Console.WriteLine()
    
    'これは成功する
    Dim value3 As String = "inline; filename=""DSC_0063 - COPY.JPG""; filename*=utf-8'ja-JP'DSC_0063%20-%20%e3%82%b3%e3%83%94%e3%83%bc%e5%8c%97%e5%9c%8b%e6%96%b0%e8%81%9e%e7%a4%be%e7%a4%be%e9%95%b7%e8%b3%9e.JPG"
    head = System.Net.Http.Headers.ContentDispositionHeaderValue.Parse(value3)
    Console.WriteLine(head.FileName)        '『"DSC_0063 - COPY.JPG"』
    Console.WriteLine(head.FileNameStar)    '『DSC_0063 - コピー北國新聞社社長賞.JPG』
    Console.WriteLine()
    
    
    Internet Explorer 向けに、あえて "%20" ではなく " " を使っている実装も
    まだまだ多そうなので(本来は RFC 違反)、そういうものにも対応させたいなら、
    結局、自前で正規表現処理するしか無さそうです。
    
    
    
    ただ、filename*= への対応は後回しにするとしても、
    とにかく文字化けでも何とかしておきたいところ。
    
    先の System.Net.Sockets.TcpClient 案は、低レベル API ゆえに
    自前でレイヤを再実装しなければならないのが、やはりネックです。
    
    https 通信時には SslStream を使う必要があったり、
    サーバー側が 301 や 302 だったら、リダイレクトの処理を
    加えたりしなければならず、汎用的な実装にするのは茨の道。
    
    
    なのでできれば、System.Net.Http 名前空間のクラスなどで対処したいところ。
    
    もしかして、System.Net.Http.HttpClient ならどうかな…と思ったんですが、
    これも駄目でした。
    
    
    Dim url As String = "http://cms1.ishikawa-c.ed.jp/~shough/NC2/htdocs/?action=common_download_main&upload_id=4537"
    Using client As New HttpClient()
        Dim request As New HttpRequestMessage(HttpMethod.Head, url)
        Dim content As HttpContent = client.SendAsync(request).Result.Content
    
        '今回の不正な Content-disposition ヘッダーを処理できていない
        'Dim headers As HttpContentHeaders = content.Headers
    
        'rawBinary.Length = 0 になってしまう。
        'Dim rawBinary As Byte() = content.ReadAsByteArrayAsync().Result
    
        'rawStream.Length = 0 になってしまう。
        'Dim rawStream As Stream = content.ReadAsStreamAsync().Result
    
        'String.Empty になってしまう。
        Dim rawString As String = content.ReadAsStringAsync().Result
    
        'そもそも、内部ストリームが既に閉じられている
        'Dim bf As BindingFlags = BindingFlags.GetField Or BindingFlags.Instance Or BindingFlags.NonPublic
        'Dim stm = DirectCast(GetType(StreamContent).InvokeMember("_content", bf, Type.DefaultBinder, content, Nothing), Stream)
        'Dim newStm As New MemoryStream()
        'stm.CopyTo(newStm)  '例外:ObjectDisposedException
    
    End Using
    
    
    
    あと思いつくのは、マネージライブラリから P/Invoke に切り替えて、
    WinHttpQueryHeaders API を試してみるという手法ぐらいです。(未検証)
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88752  Re[6]: 文字化けする画像ファイルヘッダー
□投稿者/ 魔界の仮面弁士 -(2018/09/24(Mon) 04:37:52)
    No88749 (魔界の仮面弁士) に追記
    > あと思いつくのは、マネージライブラリから P/Invoke に切り替えて、
    > WinHttpQueryHeaders API を試してみるという手法ぐらいです。(未検証)


    Windows 10 (April 2018 Update以降) に含まれる『cURL コマンド』を
    下記のように指定して使うことで、ヘッダーの生のバイナリを得る事が出来ました。

    curl.exe "http://cms1.ishikawa-c.ed.jp/~shough/NC2/htdocs/?action=common_download_main&upload_id=4537" -I


    ということで、Process クラスで curl コマンドを呼び出す方向で組み上げてみました。

    コードが長くなってしまい掲示板に書ききれないので、下記にソースを置いておきます。
    http://www.vb-user.net/junk/replySamples/2018.09.22.19.00/Module1.txt


    どの Encoding を使えば文字化けしないのかは、事前に確認できないので、
    ISO-8859-1、iso-2022-jp、Shift_JIS、UTF-8、euc-jp を順に試してみて、
    変換エラーにならなかった場合にのみ、ファイル名を解析するようにしています。
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88732  Re[4]: 文字化けする画像ファイルヘッダー
□投稿者/ ひょっとこ -(2018/09/22(Sat) 14:47:13)
    魔界の仮面弁士さん
    
    ありがとうございます。
    
    試してみたのですが、
    
    req.Method = System.Net.Http.HttpMethod.Head.Method
    と入れると
    
    
    エラー	BC30456	'Http' は 'System.Net' のメンバーではありません。
    
    というエラーが発生してしまうのですが。
    
    
    
    更に、作成くださったFunctionを使ってみたのですが
    
            Dim fff3 = AcquireFileNameFromUTF8Header("http://cms1.ishikawa-c.ed.jp/~shough/NC2/htdocs/?action=common_download_main&amp;upload_id=1545")
    
    とやっても、出力結果は空の文字列になってしまうのですが。
    
    
    更に、
    
    URLデコードも試してみたのですが
    半角文字→全角文字への変換ができないのですが。
    
        Function AcquireFileNameFromHeader(URL$) As String
    
                Dim req As HttpWebRequest = CType(WebRequest.Create(URL), HttpWebRequest)
                '  req.Method = System.Net.Http.HttpMethod.Head.Method
    
                Dim fileName As String = ""
    
    
    
                Dim res As HttpWebResponse = CType(req.GetResponse(), HttpWebResponse)
    
                ' ヘッダ情報からファイル名の取得
                Dim dispos As String = res.Headers("Content-Disposition")
    
    
                Dim dispos2 = System.Web.HttpUtility.UrlDecode(dispos)
                Dim dispos3 = Uri.UnescapeDataString(dispos)
    
    
                If Not String.IsNullOrEmpty(dispos) Then
    
                    ' filename=<ファイル名>の抜き出し
                    Dim re As New Regex(
                          "filename\s*=\s*           " &
                          "(?:                       " &
                          "  ""(?<filename>[^""]*)"" " &
                          "  |                       " &
                          "  (?<filename>[^;]*)      " &
                          ")                         " _
                          , RegexOptions.IgnoreCase _
                      Or RegexOptions.IgnorePatternWhitespace)
    
                    Dim m As Match = re.Match(dispos)
                    If m.Success Then
                        fileName = m.Groups("filename").Value
                    End If
                End If
    
    
    
                '閉じる
                If Not (res Is Nothing) Then
                    res.Close()
                End If
    
    
                Return fileName
    
    
        End Function
    
    
    
    あと、今回の問題は
    本来ISO-8859-1でエンコードするべきところをUTF-8でエンコードしてあったことが原因であることは分かったのですが、
    IE上だと正常に認識できて、ファイル名を正常に取得できています。
    
    いったい、どうやってIEはISO-8859-1とUTF-8を認識しているのでしょうか?
    
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88737  Re[5]: 文字化けする画像ファイルヘッダー
□投稿者/ 魔界の仮面弁士 -(2018/09/22(Sat) 15:35:25)
    No88732 (ひょっとこ さん) に返信
    > req.Method = System.Net.Http.HttpMethod.Head.Method
    > エラー BC30456 'Http' は 'System.Net' のメンバーではありません。

    上記は、「System.Net.Http」名前空間の「HttpMethod」クラスの「Head」プロパティを
    参照しているもので、コメントとして併記した
     req.Method = "HEAD"
    と全く同一のものです。


    > というエラーが発生してしまうのですが。
    参照設定に System.Net.Http が含まれているかを確認してみてください。
    https://docs.microsoft.com/ja-jp/dotnet/api/system.net.http.httpmethod

    それでも駄目な場合は、.NET Framework のバージョンをご確認ください。
    HttpMethod クラスは、.NET Framework 4.5 で追加されたクラスです。

    ちなみに .NET Framework 4 / 4.5 / 4.5.1 のサポートは 2年半前に終了していますので、
    サポート期間中の .NET Framework で HttpMethod クラスが使えないバージョンは
    .NET Framework 3.5 Service Pack 1 (.NET Framework 3.5.1) のみであるはずです。


    > Dim fff3 = AcquireFileNameFromUTF8Header("http://cms1.ishikawa-c.ed.jp/~shough/NC2/htdocs/?action=common_download_main&amp;upload_id=1545")
    その URL を、ブラウザーのアドレスバーに入れてみた時に、正しく画像が表示されましたか?

    正しいアドレスは
    http://cms1.ishikawa-c.ed.jp/~shough/NC2/htdocs/?action=common_download_main&amp;upload_id=1545
    ではなく
    http://cms1.ishikawa-c.ed.jp/~shough/NC2/htdocs/?action=common_download_main&upload_id=1545
    だったはずですよね。


    > URLデコードも試してみたのですが
    > 半角文字→全角文字への変換ができないのですが。
    最初の、文字化けで取得された状態の文字列を、そのまま渡したりしていませんか?

    Dim dispos2 = System.Web.HttpUtility.UrlDecode(dispos)
    で受け渡した dispos の内容が、正しく「パーセントエンコーディングされた文字列」に
    なっているかどうかを確認してみてください。
    変換元の文字列が化けているようなら、そもそも復元できるはずもないわけで。

    パーセントエンコードされた文字列であることは確認済みで、それでも
    復元されない場合、変換元のバイナリが UTF-8 で符号化されたものでは無い可能性が
    ありますので、先述した通り、HttpUtility.UrlDecodeToBytes を経由させる必要があります。


    > 本来ISO-8859-1でエンコードするべきところをUTF-8でエンコードしてあったことが原因であることは分かったのですが、
    > IE上だと正常に認識できて、ファイル名を正常に取得できています。
    その辺の事情は先に述べた通り、RFC 6266 以前ではヘッダーの国際化対応がされていなかったことに由来します。
    現在は RFC 違反だとしても、以前は未定義だったわけなので、古いサーバー実装のために、
    無理矢理解釈しているといったところでしょう。

    たとえば、最近の Internet Explorer では、UTF-8 なバイナリを解釈できますが、
    古いバージョンの IE では、Shift_JIS 相当のバイナリとして解釈される事もあります。


    > いったい、どうやってIEはISO-8859-1とUTF-8を認識しているのでしょうか?
    filename*= の場合は、その後にエンコーディングが記載されています。
    filename= の場合の解釈が、自動判定なのか、IE の設定依存なのかは知らないです。

    文字列では無く、生のバイナリ―として取得できるのなら、EncoderExceptionFallback を
    使うなどして、疑似的に文字コードを自動解釈することもできるのですが、
    相手が WebRequest クラスだと、Header は自動的に String 化されてしまうので
    手段がありません。相手が Body ならば、生バイナリを取得できるのですが。
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88734  Re[2]: 文字化けする画像ファイルヘッダー
□投稿者/ WebSurfer -(2018/09/22(Sat) 15:01:14)
    No88731 (魔界の仮面弁士 さん) に返信

    > 該当の URL にアクセスすると、Web サーバーから下記の応答が返されることを確認しました。(一部抜粋)

    使ったブラウザは何ですか? IE では文字化けするはずなのですか? Chrome を使ったとか?

    IE で ASCII 文字以外を filename に設定すると文字化けする理由は下記の記事を見てください。

    ファイルをダウンロードする ASP.NET ページで日本語ファイル名が文字化けする
    https://support.microsoft.com/ja-jp/help/436616

    Downloads and International Filenames
    https://blogs.msdn.microsoft.com/ieinternals/2010/06/07/downloads-and-international-filenames/

    自分も、

    http://cms1.ishikawa-c.ed.jp/~shough/NC2/htdocs/?action=common_download_main&upload_id=4537

    を Windows 10 Pro 64-bit, IE11 で Fiddler でキャプチャしてみましたが、応答ヘッダは以下
    のようになります。

    Expires: Sat, 29 Sep 2018 05:37:19 GMT
    Cache-Control: max-age=604800, public
    Pragma: cache
    Set-Cookie: nc_password=deleted; expires=Fri, 22-Sep-2017 05:37:18 GMT; path=/~shough/NC2/htdocs
    Content-disposition: inline; filename="DSC_0063 - R s [ k V &#1038;В .JPG"
    Etag: "541cc0-14e5f-5a360e76"
    Content-Length: 85599
    Connection: close
    Content-Type: image/jpeg

    画像を右クリックして名前を付けて保存しようとすると、

    DSC_0063 - ・スR・スs・ス[・スk・ス・ス・スV・ス・ス・スミ社抵ソス・ス・ス.JPG

    となります。

    ちなみに Chrome は以下のようになります。文字化けはしません。

    HTTP/1.1 200 OK
    Date: Sat, 22 Sep 2018 05:45:00 GMT
    Server: Apache/2.2.15 (CentOS)
    X-Powered-By: PHP/5.3.3
    Set-Cookie: nc_session=drtjda92mm19s76pjpt99stsu1; path=/~shough/NC2/htdocs
    Expires: Sat, 29 Sep 2018 05:45:00 GMT
    Cache-Control: max-age=604800, public
    Pragma: cache
    Set-Cookie: nc_password=deleted; expires=Fri, 22-Sep-2017 05:44:59 GMT; path=/~shough/NC2/htdocs
    Content-disposition: inline; filename="DSC_0063 - コピー北國新聞社社長賞.JPG"
    Etag: "541cc0-14e5f-5a360e76"
    Content-Length: 85599
    Connection: close
    Content-Type: image/jpeg

    質問者さん、ホントに IE を使ったのでしょうか? 話が矛盾してるようですけど。
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88736  Re[3]: 文字化けする画像ファイルヘッダー
□投稿者/ ひょっとこ -(2018/09/22(Sat) 15:21:20)
    ありがとうございます。

    間違いなく私が使っているのはIEです。

    Windows10 64bit
    IE11
    バージョン:11.0.15063.0

記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88739  Re[4]: 文字化けする画像ファイルヘッダー
□投稿者/ ひょっとこ -(2018/09/22(Sat) 17:53:11)
    ありがとうございます。

    うまくいきました。

    UTF-8 の場合には、AcquireFileNameFromUTF8Headerを使って、
    Shift_JIS の場合には、AcquireFileNameFromHeaderを使えば良い
    ということですよね?
    そして、.NETのWebRequest クラスだと、これらの文字コードを認識する機能はない
    ということですよね?

    もし、Shift_JIS で喋るサーバーから
    AcquireFileNameFromUTF8Headerを使って、取得した場合、
    文字化けしてしまいますか?

    もし、それが文字化けするのだとして
    もし、IEがUTF-8とShift_JISのどちらのサーバーからも正常に取得できるのだとすると
    IEは.NETで動いているわけではないので、
    バイナリ形式で取得して、文字コードを認識しているということでしょうか?

    UTF-8で喋るURLはいま手元にあるわけですが、
    Shift_JIS で喋るURLがないのでテストすることができないのですが
    どこかご存じでしょうか?


記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88741  Re[5]: 文字化けする画像ファイルヘッダー
□投稿者/ WebSurfer -(2018/09/22(Sat) 19:02:31)
    No88739 (ひょっとこ さん) に返信

    自分が Fiddler を使って確認した限りですが、サーバー側で User-Agent をみて応答を変えているようです。
    結果を以下に書いておきます。

    そこが間違いなければ、

    > UTF-8 の場合には、AcquireFileNameFromUTF8Headerを使って、
    > Shift_JIS の場合には、AcquireFileNameFromHeaderを使えば良い
    > ということですよね?

    ・・・という話にするのは無理がありそうです。


    <IE11>

    User-Agent:
    Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko

    「コピー北國新聞社社長賞」の部分のバイト列:
    0xEF, 0xBF, 0xBD, 0x52, 0xEF, 0xBF, 0xBD, 0x73, 0xEF, 0xBF, 0xBD, 0x5B, 0xEF, 0xBF, 0xBD, 0x6B,
    0xEF, 0xBF, 0xBD, 0xEF, 0xBF, 0xBD, 0xEF, 0xBF, 0xBD, 0x56, 0xEF, 0xBF, 0xBD, 0xEF, 0xBF, 0xBD,
    0xEF, 0xBF, 0xBD, 0xD0, 0x8E, 0xD0, 0x92, 0xEF, 0xBF, 0xBD, 0xEF, 0xBF, 0xBD, 0xEF, 0xBF, 0xBD

    <Chrome>

    User-Agent:
    Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36

    「コピー北國新聞社社長賞」の部分のバイト列:
    0xE3, 0x82, 0xB3, 0xE3, 0x83, 0x94, 0xE3, 0x83, 0xBC, 0xE5, 0x8C, 0x97, 0xE5, 0x9C, 0x8B, 0xE6,
    0x96, 0xB0, 0xE8, 0x81, 0x9E, 0xE7, 0xA4, 0xBE, 0xE7, 0xA4, 0xBE, 0xE9, 0x95, 0xB7, 0xE8, 0xB3,
    0x9E

    <HttpWebRequest>

    User-Agent:
    無し

    「コピー北國新聞社社長賞」の部分のバイト列:
    0xE3, 0x82, 0xB3, 0xE3, 0x83, 0x94, 0xE3, 0x83, 0xBC, 0xE5, 0x8C, 0x97, 0xE5, 0x9C, 0x8B, 0xE6,
    0x96, 0xB0, 0xE8, 0x81, 0x9E, 0xE7, 0xA4, 0xBE, 0xE7, 0xA4, 0xBE, 0xE9, 0x95, 0xB7, 0xE8, 0xB3,
    0x9E
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88738  Re[4]: 文字化けする画像ファイルヘッダー
□投稿者/ WebSurfer -(2018/09/22(Sat) 16:43:02)
    No88736 (ひょっとこ さん) に返信

    > 間違いなく私が使っているのはIEです。
    >
    > Windows10 64bit
    > IE11
    > バージョン:11.0.15063.0

    それは失礼しました。

    とすると、保存する際、日本語の名前が文字化けしないのはヘッダーを Shift_JIS で送っているからかも
    しれませんね。(未確認です)

    上に紹介した記事に書いてありますが、IE は応答ヘッダ―に ASCII 以外の文字があるときは Shift_JIS と
    して解釈する(日本語 OS の場合)そうですので。

    自分が Fiddler を間に入れて確認した際、保存すると文字化けしたのは、Fiddler で文字化けしていたと
    いうことのようです。お騒がせしてすみませんでした。

    あぷりで文字化けする原因は文字コードの解釈が正しくないことにあるような気がします。(これも気がす
    るだけで未検証・未確認ですが)
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

■88743  Re[5]: 文字化けする画像ファイルヘッダー
□投稿者/ ひょっとこ -(2018/09/22(Sat) 19:56:51)
    ありがとうございます。

    IE11のUser-Agentは
    Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko
    なのでしょうか?
    しかし、
    req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"

    を追加してみましたが、やはり文字化けしてしまいます。
記事No.88724 のレス /過去ログ152より / 関連記事表示
削除チェック/

次の20件>

<< 0 | 1 >>

パスワード/

- Child Tree -