То, что вы запрашиваете, это технически выполнимо в HTTP, поскольку ответ на любой запрос HTTP может быть фактическим файлом Excel. Например:
Использование HTTP-аутентификации:
procedure TMyForm.IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
if ARequestInfo.Document = '/myfile.xlsx' then
begin
if not ARequestInfo.AuthExists then
begin
AResponseInfo.AuthRealm := 'myserver';
Exit;
end;
if not UserIsAuthenticated(ARequestInfo.AuthUsername, ARequestInfo.AuthPassword) then
begin
AResponseInfo.ResponseNo := 403;
Exit;
end;
case ARequestInfo.CommandType of
hcGET:
begin
AResponseInfo.SmartServeFile(AContext, ARequestInfo, '<path>\myfile.xlsx');
end;
hcHEAD:
begin
AResponseInfo.ContentType := IdHTTPServer1.MIMETable.GetFileMIMEType('myfile.xlsx');
AResponseInfo.ContentLength := FileSizeByName('<path>\myfile.xlsx');
AResponseInfo.ContentDisposition := 'attachment; filename="myfile.xlsx";';
end;
else
AResponseInfo.ResponseNo := 405;
end;
end else
begin
AResponseInfo.ResponseNo := 404;
end;
end;
Использование аутентификации в HTML-форме:
index.html
<html>
<head>
<title>login</title>
</head>
<body>
<form action="/login" method="POST">
Username: <input type="text" name="user"><br>
Password: <input type="password" name="pswd"><br>
<input type="submit" value="Submit"> <input type="reset" value="Clear">
</form>
</body>
</html>
procedure TMyForm.IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
if ARequestInfo.Document = '/' then
begin
case ARequestInfo.CommandType of
hcGET, hcHEAD:
begin
AResponseInfo.ContentType := 'text/html';
if ARequestInfo.CommandType = hcGET then
AResponseInfo.ContentStream := TIdReadFileExclusiveStream.Create('<path>\index.html')
else
AResponseInfo.ContentLength := FileSizeByName('<path>\index.html');
end;
else
AResponseInfo.ResponseNo := 405;
end;
end
else if ARequestInfo.Document = '/login' then
begin
if ARequestInfo.CommandType <> hcPOST then
begin
AResponseInfo.ResponseNo := 405;
Exit;
end;
if not UserIsAuthenticated(ARequestInfo.Params.Values['user'], ARequestInfo.Params.Values['pswd']) then
begin
AResponseInfo.ResponseNo := 403;
Exit;
end;
AResponseInfo.ServeFile(AContext, '<path>\myfile.xlsx');
end else
begin
AResponseInfo.ResponseNo := 404;
end;
end;
В качестве альтернативы:
// make sure to set TIdHTTPServer.SessionState=True...
procedure TMyForm.IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
begin
if ARequestInfo.Document = '/' then
begin
case ARequestInfo.CommandType of
hcGET, hcHEAD:
begin
AResponseInfo.ContentType := 'text/html';
if ARequestInfo.CommandType = hcGET then
AResponseInfo.ContentStream := TIdReadFileExclusiveStream.Create('<path>\index.html')
else
AResponseInfo.ContentLength := FileSizeByName('<path>\index.html');
end;
else
AResponseInfo.ResponseNo := 405;
end;
end
else if ARequestInfo.Document = '/login' then
begin
if ARequestInfo.CommandType <> hcPOST then
begin
AResponseInfo.ResponseNo := 405;
Exit;
end;
if ARequestInfo.Session = nil then
begin
IdHTTPServer1.CreateSession(AContext, AResponseInfo, ARequestInfo);
end;
if not UserIsAuthenticated(ARequestInfo.Params.Values['user'], ARequestInfo.Params.Values['pswd']) then
begin
AResponseInfo.Session.Content.Values['AuthOK'] := 'no';
AResponseInfo.ResponseNo := 403;
Exit;
end;
AResponseInfo.Session.Content.Values['AuthOK'] := 'yes';
//AResponseInfo.Redirect('/myfile.xlsx');
AResponseInfo.ResponseNo := 303;
AResponseInfo.Location := '/myfile.xlsx';
end
else if ARequestInfo.Document = '/myfile.xlsx' then
begin
if ARequestInfo.AuthExists then
begin
if ARequestInfo.Session = nil then
begin
IdHTTPServer1.CreateSession(AContext, AResponseInfo, ARequestInfo);
end;
ARequestInfo.Session.Content.Values['AuthOK'] := iif(UserIsAuthenticated(ARequestInfo.AuthUsername, ARequestInfo.AuthPassword), 'yes', 'no');
end;
if (ARequestInfo.Session = nil) or (ARequestInfo.Session.Content.IndexOf('AuthOK') = -1) then
begin
//AResponseInfo.Redirect('/');
AResponseInfo.ResponseNo := 303;
AResponseInfo.Location := '/';
Exit;
end;
if ARequestInfo.Session.Content.Values['AuthOK'] <> 'yes' then
begin
AResponseInfo.ResponseNo := 403;
Exit;
end;
case ARequestInfo.CommandType of
hcGET:
begin
AResponseInfo.SmartServeFile(AContext, ARequestInfo, '<path>\myfile.xlsx');
end;
hcHEAD:
begin
AResponseInfo.ContentType := IdHTTPServer1.MIMETable.GetFileMIMEType('myfile.xlsx');
AResponseInfo.ContentLength := FileSizeByName('<path>\myfile.xlsx');
AResponseInfo.ContentDisposition := 'attachment; filename="myfile.xlsx";';
end;
else
AResponseInfo.ResponseNo := 405;
end;
end else
begin
AResponseInfo.ResponseNo := 404;
end;
end;
Однако, в любом случае, веб-браузер пользователя должен быть предварительно настроен на автоматическое открытие файлов .xlsx
в Excel (или любом другом средстве просмотра / редакторе), или, по крайней мере, для запроса пользователю, открывать ли файлы. Сервер не может заставить файлы открываться автоматически, это было бы нарушением безопасности пользователя.