RTT wrote:
> On 13-12-2011 08:31, Angus Robertson - Magenta Systems Ltd wrote:
>> I'm just about to change to HttpServer MIME handling again, to use a
>> look-up list read from the Windows classes registry or a text file)
>> when the server starts, to replace the current hard coded MIME list.
> 
> If filling from the registry, better if the list is filled dynamically
> when a not yet resolved file extension is requested. Enumerating all
> these keys is time consuming, making the server sluggish at start. And
> using memory resources, for MIME types that are not going to be
> requested, is a waste.

Is it realy that slow? I just tested this quick and dirty code, 
doesn't take too long to fill the list IMO, it returned ~190 registered
MIME types, though that number may increase on computers longer in
use than my test box:

{code}
  TMimeTypes = class(THashedStringList)
  public
    function LoadFromSystem: Boolean;
    function GetValueFromFileName(const AFileName: String): String;
    function GetValueFromFileExtension(const AFileExtension: String): String;
  end;

implementation

{ TMimeTypes }

const
  DEFAULT_MIME_TYPE = 'application/octet-stream';

function TMimeTypes.GetValueFromFileName(const AFileName: String): String;
begin
  Result := Values[ExtractFileExt(AFileName)];
  if Result = '' then
    Result := DEFAULT_MIME_TYPE;
end;

function TMimeTypes.GetValueFromFileExtension(const AFileExtension: String): 
String;
begin
  Result := Values[AFileExtension];
  if Result = '' then
    Result := DEFAULT_MIME_TYPE;
end;

{$IFDEF MSWINDOWS}
function TMimeTypes.LoadFromSystem: Boolean;

    function GetContentType(const SubKey: String; out Value: string): Boolean;
    const
      ValName = 'Content Type';
    var
      ValType: DWORD;
      KeyHandle: HKEY;
      Buf: Pointer;
      BufSize: Cardinal;
    begin
      Result := False;
      if RegOpenKeyEx(HKEY_CLASSES_ROOT, PChar(SubKey), 0, KEY_READ, KeyHandle) 
= ERROR_SUCCESS then
      begin
        if RegQueryValueEx(KeyHandle, ValName, nil, @ValType, nil, @BufSize) = 
ERROR_SUCCESS then
        begin
          GetMem(Buf, BufSize);
          if RegQueryValueEx(KeyHandle, ValName, nil, @ValType, Buf, @BufSize) 
= ERROR_SUCCESS then
          begin
            if ValType = REG_SZ then
            begin
              Value := PChar(Buf);
              Result := True;
            end;
          end;
          FreeMem(Buf);
        end;
        RegCloseKey(KeyHandle);
      end;
    end;

var
  I: Integer;
  iRes: Integer;
  S, S2: String;
  KeyHandle: HKEY;
  Buf: PChar;
  BufSize: Cardinal;
begin
  Result := RegOpenKeyEx(HKEY_CLASSES_ROOT, '', 0, KEY_READ, KeyHandle) = 
ERROR_SUCCESS;
  if Result then
  begin
    BufSize := 1024;
    GetMem(Buf, BufSize);
    I := 0;
    iRes := ERROR_SUCCESS;
    while iRes = ERROR_SUCCESS do
    begin
      BufSize := 1024;
      iRes := RegEnumKeyEx(KeyHandle, I, Buf, BufSize, nil, nil, nil, nil);
      if iRes = ERROR_SUCCESS then
      begin
        S := Buf;
        inc(I);
        if (S <> '') and (S[1] = '.') then
        begin
          if GetContentType(S, S2) then
          begin
            if IndexOfName(S) < 0 then
              Add(S + '=' + S2);
          end;
        end
        else if (S <> '') and (S[1] > '.') then
          Break;
      end;
    end;
    FreeMem(Buf);
    RegCloseKey(KeyHandle);
  end;
end;
{$ENDIF MSWINDOWS}
{code}

 


> But could be a good idea to pre-fill it with the more common ones
> (e.g. use the current hard-coded to pre-fill it). When a not in the
> list is requested, try from the registry. if found, cache it in the
> list. If not found, cache the default, application/octet-stream, one,
> so you don't loose time searching for it again, the next time it is
> requested.
--
To unsubscribe or change your settings for TWSocket mailing list
please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be

Reply via email to