Content type для файла
От: Duke_Nuken Украина  
Дата: 19.12.07 22:57
Оценка:
Для веб хендлерра нужно вытичать файл и отдать его в Response.
Вот только как на основе существующего файла определить его сontent type.
  public void ProcessRequest (HttpContext context) 
    {
        context.Response.ContentType = "image/jpeg"; //"text/plain" и тп.        
        context.Response.WriteFile(FullRealPath);
    }


тоесть FullRealPath может указывать на любой файл — картинку, архив, видео...
и естественно нужно задавать корректный ContentType для каждого файла.
Если ContentType не задан корректно, то как правило будет открываться как текст.
Тоесть содерживое бинарного файла будет выводиться в браузер.
Как тут быть?
http://FreeMusicLib.com — мой сайт с бесплатной музыкой доступной для скачивания
Re: Content type для файла
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 20.12.07 03:59
Оценка: 4 (2)
Здравствуйте, Duke_Nuken, Вы писали:

D_N>Как тут быть?

Взять компонент MimeDetector, в обработчике (System.Web.IHttHandler) выдавать поток бинарного файла пачками, к примеру, по 100 байт так:
context.Response.BinaryWrite(bytes);
По первым 100 байтам (на самом деле хватит и меньше; то есть как у вас написано — не делайте, возможны тормоза) определить Content-Type примерно таким кодом:
private static string GetContentType(byte[] bytes) {
    MimeTypes types = (MimeTypes) HttpRuntime.Cache["mimeTypes"];
    if (types == null) {
        types = new MimeTypes();
        HttpRuntime.Cache["mimeTypes"] = types;
    }
    sbyte[] data = SupportUtil.ToSByteArray(bytes);
    MimeType type = types.GetMimeType(data);
    if (type != null)
        return type.Name;
    return string.Empty;
}
Стоит это хозяйство кэшировать, иначе при каждом определении MimeDetector будет заново зачитывать свой конфигурационный файл (в нем хранится соответствие Content-Type и заголовка, можно свои типы добавлять, в принципе).

PS Прикрутил MimeDetector к своему BinaryHandler-у минут за 30 — работает отлично, жалоб не имею.
Re[2]: Content type для файла
От: Duke_Nuken Украина  
Дата: 21.12.07 22:04
Оценка:
Да, работает довольно не плохо. Вот только с этими хендлерами попутно еще одна проблемма.
Дето в том что когда запрашиваеться файл и он отдаеться через хендлер, то как при сохранении
указать его оригинальное имя. Тоесть например файл my.mp3 и запрос на него www.something.com/file.ashx?filename=my.mp3
то когда хендлер вычитает этот файл и отдаст его в респорс, то браузер предложит его сохранить,
но имя файла для сохранения будет file.ashx, а не my.mp3. Как то это можно изменить?


Здравствуйте, rsn81, Вы писали:
R>Взять компонент MimeDetector, в обработчике (System.Web.IHttHandler) выдавать поток бинарного файла пачками, к примеру, по 100 байт так:
context.Response.BinaryWrite(bytes);
По первым 100 байтам (на самом деле хватит и меньше; то есть как у вас написано — не делайте, возможны тормоза) определить Content-Type примерно таким кодом:
private static string GetContentType(byte[] bytes) {
R>    MimeTypes types = (MimeTypes) HttpRuntime.Cache["mimeTypes"];
R>    if (types == null) {
R>        types = new MimeTypes();
R>        HttpRuntime.Cache["mimeTypes"] = types;
R>    }
R>    sbyte[] data = SupportUtil.ToSByteArray(bytes);
R>    MimeType type = types.GetMimeType(data);
R>    if (type != null)
R>        return type.Name;
R>    return string.Empty;
R>}
Стоит это хозяйство кэшировать, иначе при каждом определении MimeDetector будет заново зачитывать свой конфигурационный файл (в нем хранится соответствие Content-Type и заголовка, можно свои типы добавлять, в принципе).


R>PS Прикрутил MimeDetector к своему BinaryHandler-у минут за 30 — работает отлично, жалоб не имею.
http://FreeMusicLib.com — мой сайт с бесплатной музыкой доступной для скачивания
Re[3]: Content type для файла
От: Roman Odaisky Украина  
Дата: 21.12.07 22:27
Оценка: 6 (2)
Здравствуйте, Duke_Nuken, Вы писали:

D_N>Да, работает довольно не плохо. Вот только с этими хендлерами попутно еще одна проблемма.

D_N>Дето в том что когда запрашиваеться файл и он отдаеться через хендлер, то как при сохранении
D_N>указать его оригинальное имя. Тоесть например файл my.mp3 и запрос на него www.something.com/file.ashx?filename=my.mp3
D_N>то когда хендлер вычитает этот файл и отдаст его в респорс, то браузер предложит его сохранить,
D_N>но имя файла для сохранения будет file.ashx, а не my.mp3. Как то это можно изменить?

1. Оверквотинг и топпостинг не рулят.
2. Это уже вопрос по HTTP, не по ASP. Тебе нужно Content-Disposition: attachment; filename="porn.avi".
3. Если IIS умеет отдавать файлы с любыми расширениями, то научите, наконец, RSDN Team этому! А то с files.rsdn.ru файлы с неизвестными ему расширениями не отдаются.
До последнего не верил в пирамиду Лебедева.
Re[4]: Content type для файла
От: Duke_Nuken Украина  
Дата: 22.12.07 00:38
Оценка:
Спасибо, очень полезная инфа. Так сказать последний штрих...
Выглядит примерно вот так
    public void ProcessRequest (HttpContext context) 
    {
        context.Response.Clear();
        context.Response.AppendHeader("Content-Disposition", "attachment; filename=\"putty.exe\"");
        context.Response.ContentType = "application/octet-stream";
        context.Response.Flush();
        context.Response.WriteFile(@"c:\Duke\download\putty.exe");
    }

В результате выпадает окошко сохранения с корректным именем файла. Что и требовалось.

Здравствуйте, Roman Odaisky, Вы писали:

RO>1. Оверквотинг и топпостинг не рулят.

RO>2. Это уже вопрос по HTTP, не по ASP. Тебе нужно Content-Disposition: attachment; filename="porn.avi".
RO>3. Если IIS умеет отдавать файлы с любыми расширениями, то научите, наконец, RSDN Team этому! А то с files.rsdn.ru файлы с неизвестными ему расширениями не отдаются.
http://FreeMusicLib.com — мой сайт с бесплатной музыкой доступной для скачивания
Re[4]: Content type для файла
От: Sinclair Россия https://github.com/evilguest/
Дата: 25.12.07 05:51
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:
RO>3. Если IIS умеет отдавать файлы с любыми расширениями, то научите, наконец, RSDN Team этому!
Нет, не умеет. By design.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Content type для файла
От: mogadanez Чехия  
Дата: 25.12.07 17:34
Оценка: 83 (2)
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Roman Odaisky, Вы писали:

RO>>3. Если IIS умеет отдавать файлы с любыми расширениями, то научите, наконец, RSDN Team этому!
S>Нет, не умеет. By design.

хмм... если мы об одном и том же, "IIS 6.0 does not serve unknown MIME types"
то это можно настроить: http://support.microsoft.com/default.aspx/kb/326965
Re[6]: Content type для файла
От: Sinclair Россия https://github.com/evilguest/
Дата: 26.12.07 03:28
Оценка:
Здравствуйте, mogadanez, Вы писали:
M>хмм... если мы об одном и том же, "IIS 6.0 does not serve unknown MIME types"
M>то это можно настроить: http://support.microsoft.com/default.aspx/kb/326965
Ну нифига себе!
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[7]: Content type для файла
От: mogadanez Чехия  
Дата: 31.12.07 14:17
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, mogadanez, Вы писали:

M>>хмм... если мы об одном и том же, "IIS 6.0 does not serve unknown MIME types"
M>>то это можно настроить: http://support.microsoft.com/default.aspx/kb/326965
S>Ну нифига себе!

атож....


P.S. время видел, знаю.... но в магадане уже наступиЛ =))
Re[5]: Content type для файла
От: Duke_Nuken Украина  
Дата: 07.01.08 07:54
Оценка:
Вот тут проблемма нашлась. Если имя файла написано в юникоде,
то при скачивании сохраняет каракули всякие.
    public void ProcessRequest (HttpContext context) 
    {
        context.Response.Clear();
        context.Response.AppendHeader("Content-Disposition", "attachment; filename=\"Мой файл.exe\"");
        context.Response.ContentType = "application/octet-stream";
        context.Response.Flush();
        context.Response.WriteFile(@"c:\Duke\download\putty.exe");
    }


Можно както заставить браузер читать хедер как юникод?

RO>>1. Оверквотинг и топпостинг не рулят.

RO>>2. Это уже вопрос по HTTP, не по ASP. Тебе нужно Content-Disposition: attachment; filename="porn.avi".
RO>>3. Если IIS умеет отдавать файлы с любыми расширениями, то научите, наконец, RSDN Team этому! А то с files.rsdn.ru файлы с неизвестными ему расширениями не отдаются.
http://FreeMusicLib.com — мой сайт с бесплатной музыкой доступной для скачивания
Re[6]: Content type для файла
От: rameel https://github.com/rsdn/CodeJam
Дата: 09.01.08 07:01
Оценка:
Здравствуйте, Duke_Nuken, Вы писали:

D_N>Можно както заставить браузер читать хедер как юникод?


Re[5]: Загрузка файла на клиента
Автор: rameel
Дата: 30.12.07
... << RSDN@Home 1.2.0 alpha rev. 774 >>
Re[7]: Content type для файла
От: Duke_Nuken Украина  
Дата: 09.01.08 12:26
Оценка:
Если закодировать Server.UrlPathEncode(filename) то пашет, но только для IE, а firefox фигню роказывает
а не имя файла. С HttpUtility.UrlPathEncode(filename) таже фигня.

private static string EncodeFileName(string userAgent, string filename)
{
    if (userAgent.ToLower().IndexOf("msie") != -1)
        filename = HttpUtility.UrlPathEncode(filename);

    return string.Format("\"{0}\"", filename);
}



Здравствуйте, rameel, Вы писали:

R>Здравствуйте, Duke_Nuken, Вы писали:


D_N>>Можно както заставить браузер читать хедер как юникод?


R>Re[5]: Загрузка файла на клиента
Автор: rameel
Дата: 30.12.07
http://FreeMusicLib.com — мой сайт с бесплатной музыкой доступной для скачивания
Re[8]: Content type для файла
От: rameel https://github.com/rsdn/CodeJam
Дата: 09.01.08 12:39
Оценка:
Здравствуйте, Duke_Nuken, Вы писали:

D_N>Если закодировать Server.UrlPathEncode(filename) то пашет, но только для IE, а firefox фигню роказывает

D_N>а не имя файла. С HttpUtility.UrlPathEncode(filename) таже фигня.

Для Firefox ничего кодировать не надо, он и так понимает. Смотри внимательно код. Вот насчет Оперы не знаю, проверяй сам
... << RSDN@Home 1.2.0 alpha rev. 774 >>
Re: Content type для файла
От: Pavel_Agurov Россия  
Дата: 10.01.08 14:11
Оценка:
D_N>Вот только как на основе существующего файла определить его сontent type.

Вот так можно:

using System;
using Microsoft.Win32;

namespace FileTypeByExt
{
  class Class1
  {
    [STAThread]
    static void Main(string[] args)
    {
      // Тип (content) по-умолчанию
      const string DEFAULT_CONTENT_TYPE = "application/unknown";

      string  fileContentType;

      // Расширение файла
      string fileExtension = ".jpeg";

      try 
      {
        // Ищем в реестре вертку, соответствующую расширению
        RegistryKey fileextkey =
                   Registry.ClassesRoot.OpenSubKey(fileExtension);
        // Получаем тип
        fileContentType = fileextkey.GetValue("Content Type",
                        DEFAULT_CONTENT_TYPE).ToString();
      }
      catch (Exception e)
      {
        fileContentType = DEFAULT_CONTENT_TYPE;
        Console.WriteLine(e.Message);
      }
            
      Console.WriteLine(fileContentType);
    }
  }
}
Re[6]: Content type для файла
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.01.08 04:34
Оценка:
Здравствуйте, Duke_Nuken, Вы писали:

D_N>Вот тут проблемма нашлась. Если имя файла написано в юникоде,

D_N>то при скачивании сохраняет каракули всякие.
D_N>
D_N>    public void ProcessRequest (HttpContext context) 
D_N>    {
D_N>        context.Response.Clear();
D_N>        context.Response.AppendHeader("Content-Disposition", "attachment; filename=\"Мой файл.exe\"");
D_N>        context.Response.ContentType = "application/octet-stream";
D_N>        context.Response.Flush();
D_N>        context.Response.WriteFile(@"c:\Duke\download\putty.exe");
D_N>    }
D_N>


D_N>Можно както заставить браузер читать хедер как юникод?

Я полагаю, что стоит почитать RFC 2047.
RO>>>1. Оверквотинг и топпостинг не рулят.
RO>>>2. Это уже вопрос по HTTP, не по ASP. Тебе нужно Content-Disposition: attachment; filename="porn.avi".
RO>>>3. Если IIS умеет отдавать файлы с любыми расширениями, то научите, наконец, RSDN Team этому! А то с files.rsdn.ru файлы с неизвестными ему расширениями не отдаются.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.