Send mail with special characteres and Indy - freepascal

I try to send email. In the body of TIdMessage I have a string with 'ménage'. After the IdMessage is send via an IdSMTP. If my program run under Windows (compiled with Lazarus), no problem. If my program is compiled and run under Linux, I get 'propreté'. I have try meDefault, meMIME and mePlainText for the encoding property of the IdMessage, nothing to do I allways have the error.
Thanks for your help.

I am with Lazarus 2.0.6 on Raspberry PI. I have changed a little bit my code, now the special characteres are ok inside the message, but not in the subject of my email!!??
IdMessage.Clear;
IdMessage.IsEncoded := True;
IdMessage.ContentTransferEncoding := 'base64';
IdMessage.Encoding := meMime;
IdMessage.ContentType := 'text/plain';
IdMessage.Charset := 'UTF-8';
IdMessage.Date:=Now; //Date de l'envoi du message
IdMessage.Subject:='Propreté'; //Sujet du message
IdMessage.Priority:=mpNormal; //Priorité du message
Thanks

Related

Delphi IE11 instance, OleSysErrorOLE A system shutdown has already been scheduled/8150002E

I have a Delphi app which prints HTML to PDF by opening the document in IE11 in the background and using the default PDF printer to print to PDF. This process works fine.
The issue is the following:
(Example I want to print 5 HTML documents to PDF.)
On the first run, it processes the first document fine, but then skips the rest with the following errors:
On Win Server 2016:
EOleSysErrorOLE A system shutdown has already been scheduled.
On Windows 10:
EOleSysErrorOLE error 8150002E
Then I wait until "iexplore.exe" closes, which takes a few sec.
From then, it processes all documents just fine regardless the number of the documents.
If I do not use the app for a long time (approx a day), it does the same as above.
It skips on the first run, then waits a few seconds and then us fine.
I tried to use OleVariant and IWebBrowser2, but both have the same outcome.
I close the Object with .Quit. (see in code below). I also tried Unassigned, Free, setting the Object to Null before creating a new object. None of them worked. Same outcome.
Here are a few thing which I tried as a workaround:
If I do not use .Quit, it works fine, but obviously won't close any iexplore.exe.
Also, if I open an IE window (GUI) and minimize it, the HTML-PDF process works fine.
I also tried to call to create a background IE object on TMainForm.FormCreate() when the app starts, and it works as well.
When it gets to the HTML-PDF process, it creates a new IE background object (additional "iexplore.exe") and closes it by leaving the one created on FormCreate().
I would like to figure out why it just cannot create and close an object fast enough on the first run (without having an IE opened or without using .Quit).
Here is the code:
Note: The program also writes some stuff to the registry, but I cut some lines for simplicity (I also might cut a few end here and there. Note that the function works fine apart than the issue above).
function THTMLMergeDocument.FilePrint: boolean;
var
BrowserObject: OleVariant;
ie : IWebBrowser2;
vaIn, vaOut: OleVariant;
OldHeader, OldFooter, OldPrinterName: String;
OldOrientation: Integer;
Registry : TRegistry;
ST, TOutVal: TDateTime;
sUrl : string;
Flag, TargetFrameName, PostData, Headers : OleVariant;
begin
result := false;
try
if fPrinterName = VTPrint.GetDefaultPrinter then
begin
try
//Tried OleVariant
{
BrowserObject := Unassigned;
BrowserObject := CreateOleObject('InternetExplorer.Application');
BrowserObject.Silent := true;
BrowserObject.Visible := false;
BrowserObject.Navigate('file:\\'+DocumentFileName);
BrowserObject.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER);
while BrowserObject.Busy or BrowserObject.ReadyState <> READYSTATE_COMPLETE do
begin
Application.ProcessMessages;
end;
}
//Tried IWebBrowser2
ie := CoInternetExplorer.Create;
sUrl := 'file:\\'+DocumentFileName;
ie.Navigate(sUrl, Flag, TargetFrameName, PostData, Headers);
ie.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER,vaIn,vaOut);
while ie.ReadyState <> READYSTATE_COMPLETE do
begin
Application.ProcessMessages;
end;
if (PDFOutput) then
begin
ST := Now;
TOutVal := EncodeTime(0,DocumentServerOptions.PDFConverterTimeOutInterval,0,0);
while not PDF.Completed and (Now-ST<TOutVal) do
Application.ProcessMessages;
if PDF.Completed then
result := true
else
WinWordLogProc('ERROR: No response received from PDF converter');
end
else
begin
result := true;
end;
ie.Quit; //close IWebBrowser2 object
BrowserObject.Quit; //close OleVariant object
except on E: Exception do
WinWordLogProc( 'Error class: ' + E.ClassName + #13 + E.Message);
end;
end
else
begin
WinWordLogProc('Error setting default printer to '+fPrinterName);
end;
finally
VTPrint.SetDefaultPrinter(OldPrinterName);
end;
`
I suspect that it has something do do with the IE object handling, but I'm not sure, hence asking for help here.
The browser's Navigate() method is asynchronous. You should wait for the document to finish loading before you then call ExecWB() to print the document, not after calling it.

Minio: how to get right link to display image on html

I need to get images from Minio bucket, but I cannot display that image.
I found out that problem was in link. I cannot open it even with browser. So, here is the problem:
GET https://127.0.0.1:9000/myphotos/Jungles.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=7PAB237ARMGX7RTYHUSL%2F20221202%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20221202T133028Z&X-Amz-Expires=604800&X-Amz-Security-Token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiI3UEFCMjM3QVJNR1g3UlRZSFVTTCIsImV4cCI6MTY3MDAyNzIyNiwicGFyZW50IjoiS2VtYWxBdGRheWV3In0.okb2wO_iLhOlwWeNbixec4R5MRgGw2_KCY_SB9NfuseUI3g9gzTccycbaA6UnZiuuLzbpxPM5tR_hnxa_Y8zWQ&X-Amz-SignedHeaders=host&versionId=null&X-Amz-Signature=281fab24bbe3d651f89c160f5a613512f5e4503f40300ef0008ac94bd9c8f90b
net::ERR_CONNECTION_REFUSED
My code that has been used to upload that file:
package main
import (
"context"
"log"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
)
func main() {
ctx := context.Background()
endpoint := "play.minio.io"
accessKeyId := "KemalAtdayew"
secretAccessKey := "K862008971a!"
useSSL := true
// init minio client object
minioClient, err := minio.New(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(accessKeyId, secretAccessKey, ""),
Secure: useSSL,
})
if err != nil {
log.Fatalln(err)
}
// make a new bucket called myphoto
bucketName := "photobucket"
location := "us-east-1"
err = minioClient.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{Region: location})
if err != nil {
// check to see if we already own this bucket
exists, errBucketExists := minioClient.BucketExists(ctx, bucketName)
if errBucketExists == nil && exists {
log.Printf("We already own %s\n", bucketName)
} else {
log.Fatalln(err)
}
} else {
log.Printf("Successfully created %s\n", bucketName)
}
// upload you photos
objectName := "Jungles.jpeg"
filePath := "/minio-1/Jungles.jpeg"
contentType := "image/jpeg"
// upload the zip file FPutObject
info, err := minioClient.FPutObject(ctx, bucketName, objectName, filePath, minio.PutObjectOptions{ContentType: contentType})
if err != nil {
log.Fatalln(err)
}
log.Printf("Successfully uploaded %s of size %d\n", objectName, info.Size)
}
I also gave permission and made it public. Still nothing.
<!DOCTYPE html>
<html>
<head>
<title> Minio </title>
<meta charset="utf-8">
</head>
<body>
<div>
<img src="https://127.0.0.1:9000/myphotos/Jungles.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=7PAB237ARMGX7RTYHUSL%2F20221202%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20221202T124101Z&X-Amz-Expires=604800&X-Amz-Security-Token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NLZXkiOiI3UEFCMjM3QVJNR1g3UlRZSFVTTCIsImV4cCI6MTY3MDAyNzIyNiwicGFyZW50IjoiS2VtYWxBdGRheWV3In0.okb2wO_iLhOlwWeNbixec4R5MRgGw2_KCY_SB9NfuseUI3g9gzTccycbaA6UnZiuuLzbpxPM5tR_hnxa_Y8zWQ&X-Amz-SignedHeaders=host&versionId=null&X-Amz-Signature=5027bd8021a58548ce6be5dead3b622afd951f157a289320ef7dab7701baa7d2" alt="Photo from Minio">
</div>
</body>
</html>
Tried to change html code. Then, found out that it's not html problem.
Tried to share in any other possible way except than, "bucket->click on photo -> click on share"
Link is invalid, but there is no other proper way to get link to that image in bucket.
The path to your local image seems to be strange. Verify if you can open your image manually, and remove all the parameters after the image extension, it should be Forest.jpg
The path to your local image seems to be strange. Verify if you can open your image manually, and remove all the parameters after the image extension, it should be Forest.jpg
If you have Minio running in a container, it is always a mess with 127.0.0.1 or localhost.
Try to generate the link with the minioclient.
mc alias set myminio http://localhost:9000 user password
mc share download myminio/mybucket/object.txt
it will return something like this:
mc share download --recursive minio/testbucket
URL: http://localhost:9000/testbucket/KUBERNETES_AN_ENTERPRISE_GUIDE.pdf
Expire: 7 days 0 hours 0 minutes 0 seconds
Share: http://localhost:9000/testbucket/KUBERNETES_AN_ENTERPRISE_GUIDE.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=minioadmin%2F20221207%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20221207T130336Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=8668da57727f04e7c7e8b15f5d8852fa3801e323cfbc6198384737b77f54cb0b
That link you can open in your Browser.
Note --recursive generate links for all the uploaded files in the bucket.
To get one specific use:
mc share download myminio/testbucket/object.txt.
In production mode as you will use full qualified domain names and not 127.0.0.1 or localhost.
Take a look here about the mc command for generating the link.
https://min.io/docs/minio/linux/reference/minio-mc/mc-share-download.html
If you have a backend and according to your programming language you can also generate links through the api.
Here you find a example for javascript:
https://min.io/docs/minio/linux/developers/javascript/API.html#presignedUrl

What causes browsers to open "Save As" window when downloading dynamic content?

I am experimenting with an idea to stream dynamic data from a web server into a file on the client device. To implement this idea, I am making use of the HTTP Content-Disposition response header and the HTML download attribute. The following is my sample code, where the server is implemented in Go:
HTML:
<a href="download" download>Download</a>
Server:
package main
import (
"fmt"
"net/http"
"time"
)
func main() {
// Handle download request.
http.HandleFunc("/download", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Disposition", "attachment; filename=\"log.txt\"")
w.Write([]byte("first message\n"))
time.Sleep(10 * time.Second)
// The following for-loop takes about 30 seconds to run on my dev machine.
for i := 0; i < 1000000; i++ {
timestamp := time.Now().Unix()
log(timestamp)
w.Write([]byte(fmt.Sprintf("%v\n", timestamp)))
time.Sleep(time.Microsecond)
}
log("done")
})
// Start HTTP server.
if err := http.ListenAndServe(":8080", nil); err != nil {
log(err)
}
}
func log(v ...interface{}) {
fmt.Println(v...)
}
This sample code works in that it successfully downloads all the content from the download handler when clicking on the "Download" link. However, I am observing the following behavior that I am unable to explain:
I have my browser configured to always ask where to save the downloaded files. When running the sample code above, Chrome opens the Save As window only after the 10 second sleep but before the for-loop is complete and in turn the handler function has returned. Why did Chrome not present the Save As window when the "first message" was sent before the 10 second sleep? What is different between the "first message" and the messages being sent in the for-loop that causes the Save As window to only open when the for-loop starts?
Aside: If FileSystemWritableFileStream had greater cross-browser support, I'd use that to stream dynamic server data directly into a file on the client side.
Go's http.ResponseWriter has a default 4KB buffer, defined at the Transport level:
type Transport struct {
// ...
// WriteBufferSize specifies the size of the write buffer used
// when writing to the transport.
// If zero, a default (currently 4KB) is used.
WriteBufferSize int
// ...
}
In some instances, when using standard responses, you can make use the Flush method by using type assertion with the http.Flusher interface to send the bytes right away:
if f, ok := w.(http.Flusher); ok {
f.Flush()
}
To have Firefox open the Save As window immediately after "first message" is sent, Ricardo Souza's answer appears to be all that's needed. To have Chrome do the same, the response's Content-Type header also needs to be set to anything other than the default text/plain (thanks to this SO answer). Example:
w.Header().Set("Content-Type", "application/octet-stream; charset=utf-8")

Delphi JQtouch Web Broker Demo Code not Behaving due to HTTP Response Content-Type charset

I am implementing an application using Delphi XE2 Rest/JSON Server and jQTouch client. I have pretty much finished the server side and am now moving onto the client side development.
I have downloaded the jQTouch source and have set it up under IIS on port 8081 of my PC. This works fine.
But I need the static demo source to be accessible via a Delphi WebFileDispatcher.
This is where I have the problem...
As a stripped down test/proof, I have set this up using the Web Broker / Web Server Application / Standalone VCL wizard, and dropped a WebFileDispatcher onto the Web Module. The only config has been to configure the 'Root' of the WebFileDispatcher to pick up the content.
Here's the problem reproduced in its most simple form:
I can access the content via IIS on port 8081.
I can access the content via Web Broker on port 8080.
Both using exactly the same localhost URL, just different ports.
So I know my paths and basic config are correct.
BUT... the 'Greater Than' or 'Right Arrows' on the jQTouch menu items are appearing as an 'a' with a circumflex when the content is server up from Web Broker. The green external link arrows are appearing with a Euro symbol on them.
The content appears without any problem when server up from IIS.
The problem appears to be the charset that is being appended to the content-type by code in the IdHTTPHeaderInfo unit. This unit is adding 'charset=8859-1' when the html and css files are UTF-8.
I can fix this by changing the MimeTypes defined in the WebFileExtensions property of the WebFileDispatcher to include charset=UTF-8. i.e. change the entry for 'text/html' to 'text/html; charset=UTF-8'.
But should this be required? I don't think so. I think that either:
A) If Delphi includes a web server that is serving these files and its default is to assume all text files are 8859-1, then the mime types of the web dispatcher should be setup to override this to the correct value of UTF-8.
B) Or the files should be checked for head meta tags for the actual encoding to be reported in the response.
At the moment, neither of these seem to be the case.
Would anybody else class this as a bug that needs reporting?
It has taken two days to narrow the problem down this far, and I wouldn't want anyone else to have to do this in the future.
See W3.org - Handling Character Encodings
To reproduce, just download the latest jQTouch release and map the content to a WebFileDispatcher.
Here are two images that show the problem:
![enter image description here][2]
Also, below are the Delphi files relating to the configuration of the Web Module..
Here is the PAS file...
unit WebModuleUnit1;
interface
uses System.SysUtils, System.Classes, Web.HTTPApp;
type
TWebModule1 = class(TWebModule)
WebFileDispatcher1: TWebFileDispatcher;
procedure WebModule1DefaultHandlerAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;
var
WebModuleClass: TComponentClass = TWebModule1;
implementation
{$R *.dfm}
procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
Response.Content := '<html><heading/><body>Web Server Application</body></html>';
end;
end.
And here is the dfm...
object WebModule1: TWebModule1
OldCreateOrder = False
Actions = <
item
Default = True
Name = 'DefaultHandler'
PathInfo = '/'
OnAction = WebModule1DefaultHandlerAction
end>
Height = 230
Width = 415
object WebFileDispatcher1: TWebFileDispatcher
WebFileExtensions = <
item
MimeType = 'text/css'
Extensions = 'css'
end
item
MimeType = 'text/html'
Extensions = 'html;htm'
end
item
MimeType = 'text/javascript'
Extensions = 'js'
end
item
MimeType = 'image/jpeg'
Extensions = 'jpeg;jpg'
end
item
MimeType = 'image/x-png'
Extensions = 'png'
end>
WebDirectories = <
item
DirectoryAction = dirInclude
DirectoryMask = '*'
end
item
DirectoryAction = dirExclude
DirectoryMask = '\templates\*'
end>
RootDirectory = 'C:\WebRoot'
Left = 80
Top = 64
end
end
[2]:

TRichMemo - LoadRichText not working

I am trying to save the contents of a TRichMemo to TMemoryStream, and then be able to load the formatted data back from the stream into the rich memo.
The problem is LoadRichText is failing for some reason. I know the data is been saved to my stream because I can actually save it fo file as rtf and view it externally.
This is basically what I have:
var
FMyStream: TMemoryStream;
To save:
RichMemo1.SaveRichText(FMyStream);
To load:
FMyStream.Seek(0, soBeginning);
if not RichMemo1.LoadRichText(FMyStream) then
raise Exception.Create('Failed to load data from stream.');
As I said the data is saved to stream correctly, but trying to load into the rich memo is hitting my exception everytime.
What could be the problem?
The code for the LoadRichText function is:
function TCustomRichMemo.LoadRichText(Source: TStream): Boolean;
begin
if Assigned(Source) and HandleAllocated then begin
Result := TWSCustomRichMemoClass(WidgetSetClass).LoadRichText(Self, Source);
if not Result and Assigned(RTFLoadStream) then begin
Self.Lines.BeginUpdate;
Self.Lines.Clear;
Result:=RTFLoadStream(Self, Source);
Self.Lines.EndUpdate;
end;
end else
Result := false;
end;
and SaveRichText code:
function TCustomRichMemo.SaveRichText(Dest: TStream): Boolean;
begin
if Assigned(Dest) and HandleAllocated then begin
Result := TWSCustomRichMemoClass(WidgetSetClass).SaveRichText(Self, Dest);
if not Result and Assigned(RTFSaveStream) then
Result:=RTFSaveStream(Self, Dest);
end else
Result := false;
end;
Thanks.
Ok, I found the solution to my problem.
At first I created a simple test project and LoadRichText and SaveRichText worked, which meant the problem was within my code somewhere...
My stream is declared in a class in a separate unit. In another form I have my rich memo control, when the form is closed the data is saved to the stream, that part I knew worked because I could save it to file and view it externally.
The problem was when I was creating the form that contains my rich memo, I was calling LoadRichText from the FormCreate event. So I moved it into FormActivate and now it works without error.