I want to submit a form using the CHttpFile::SendRequest and save those data to a mysql database. The field inside the DB table collation is also set to utf8mb4_unicode_ci.
It works fine except the character encoding for the non-english chars. My app is under MFC and "character set" is no set which means ASCII. I tried to convert the chars to unicode without success.
CString strFormData;
strFormData = _T(SUBMIT_FORM) + _T(strSubmitValue) + _T(USERNAME_FIELD) + _T(m_strUsername) + _T(RESTORE_EMAIL_FIELD) + _T(m_strRestoreEmail) + _T(CAPTCHA_FIELD);
LPWSTR lpUnicodeFormData = A2W( strFormData );
strHeaders = _T("Content-Type: application/x-www-form-urlencoded;charset=UTF-8\r\n");
result = pFile->SendRequest(strHeaders, (LPVOID) (LPCTSTR) lpUnicodeFormData, wcslen(lpUnicodeFormData));
What am i doing wrong here ?
Inside PHP file where the html form exists, I added the code
mysqli_set_charset($con, "utf8");
This solved the problem.
thank you to all.
Related
I am trying to build an AWS Signature Version 4 Request in Delphi.
I manage to handle the signing part but have some issue with the Canonical Request
I am following the link below to create a Canonical Request
https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
If I do it in Python3 see code below
I get the correct answer
f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59
I am trying to do the same in Delphi
The result is WRONG code
bfc216a33de74e30285fc72d6dd2035508e9aec861e5d56b59f4c1eb4f29ddc3
Anyone now howto do this Python line below in Delphi
PYTHON
canonical_request_hash = hashlib.sha256((canonical_request).encode('utf-8')).hexdigest()
And get this result
f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59
PYTHON CODE
canonical_request = "GET\n"+"/\n"+"Action=ListUsers&Version=2010-05-08\n"+"content-type:application/x-www-form-urlencoded; charset=utf-8\n"+"host:iam.amazonaws.com\n"+ "x-amz-date:20150830T123600Z\n"+ "\n"+ "content-type;host;x-amz-date\n"+ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
canonical_request_hash = hashlib.sha256((canonical_request).encode('utf-8')).hexdigest()
print(canonical_request_hash)
DELPHI
canonical_request := 'GET\n'+'/\n'+'Action=ListUsers&Version=2010-05-08\n';
canonical_request := canonical_request +'content-type:application/x-www-form-urlencoded; charset=utf-8\n'+'host:iam.amazonaws.com\n'+ 'x-amz-date:20150830T123600Z\n"+ "\n"+ "content-type;host;x-amz-date\n'+ 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
canonical_request_hashed := BytesToHexConverter ( THashSHA2.GetHashBytes(UTF8Encode( canonical_request ))); // Struggle
memo1.Lines.Add(canonical_request_hashed);
memo1.Lines.Add('f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59');
//*********************
function TForm1.BytesToHexConverter(b: Tbytes): string;
var
I : Integer;
s : String;
begin
s:='';
for i := 0 to length(b)-1 do
begin
s:=s+b[i].ToHexString;
end;
s:= LowerCase(s);
result:=s;
End;
I expect this result in delphi
f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59
but get this
bfc216a33de74e30285fc72d6dd2035508e9aec861e5d56b59f4c1eb4f29ddc3
Your'e trying to calculate SHA256 hash from the sample cannonical request that appears on AWS documentation page. As plain text it reads:
GET
/
Action=ListUsers&Version=2010-05-08
content-type:application/x-www-form-urlencoded; charset=utf-8
host:iam.amazonaws.com
x-amz-date:20150830T123600Z
content-type;host;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
You've successfully converted this plain text to Python string, but you failed to do that in Delphi because of two reasons:
You copy-pasted Python code to Delphi and replaced some " with ', but not all of them as the comment below the question points out.
Delphi doesn't allow backslash escapes within string literals. You can only escape single quote ' by typing two single quotes ''. All other characters you either type directly or use # -prefixed character literals. So you should also convert all occurences of \n to #10 (new line character) and put it outside of string literal.
The correct translation to Delphi is:
canonical_request :=
'GET'#10 +
'/'#10 +
'Action=ListUsers&Version=2010-05-08'#10 +
'content-type:application/x-www-form-urlencoded; charset=utf-8'#10 +
'host:iam.amazonaws.com'#10 +
'x-amz-date:20150830T123600Z'#10 +
#10 +
'content-type;host;x-amz-date'#10 +
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';
In the end it turns out that it's not a hexdigest() issue as written in the title, but rather an issue of porting Python code to Delphi.
I've tried to develop an NSIS Plugin in C++.
Here is my method to set informations from NSIS:
void __declspec(dllexport) SetCredentials(HWND hWndParent, int string_size, TCHAR *variables, stack_t **stacktop, extra_parameters *extra) {
EXDLL_INIT();
server = getuservariable(INST_0);
port = myatou(getuservariable(INST_1));
database = getuservariable(INST_2);
username = getuservariable(INST_3);
password = getuservariable(INST_4);
MessageBox(hWndParent, server, L"Info", MB_OK); // Here is the problem
setuservariable(INST_0, server);
}
Sample:
OutFile "Example.exe"
BrandingText " "
Section
MySQL::SetCredentials "localhost" 3306 "banananode" "root" ""
Pop $0
MessageBox MB_OK "Server: $0" ; Returns the server value...
SectionEnd
The Problem is, when i try to print out the server variable, chinese characters will be shown, not the correct text:
When i return the value with setuservariable(INST_0, server);, NSIS will be display it correctly:
Can you tell me, whats wrong?
I've tried to build the resulted .dll with pluginapi-x86-ansi.lib and pluginapi-x86-unicode.lib but the result is the same...
ANSI characters interpreted as Unicode (UTF-16LE) tends to look Chinese.
When you create a Unicode plug-in you need to:
Make sure UNICODE and _UNICODE is defined in your project/.C files.
Link with pluginapi-x86-unicode.lib
Add Unicode True to your .NSI
Place the plug-in in \NSIS\x86-unicode
In your case you most likely forgot about Unicode True. Returning the value works because you never actually changed the memory of server, it is still the same input string.
I call my service in wcf as you can see :
ClientRequest.Headers["Content-type"] = "application/json";
string result = ClientRequest.DownloadString(ServiceHostName + "/NajaService.svc/GetCarData/" + plaque);
var javascriptserializer = new JavaScriptSerializer();
return javascriptserializer.Deserialize<NajaResult>(result);
But the returned data is like this :
{"CarColor":"آبي سير","CarModel":"1383","CarTip":"ال ايکس","CarType":"سواري","Chassis":"83844131","Family":"####","FuelType":1,"MotorNum":"12483068683","Name":"####","NationalCode":"0000000000","Plaque":"11-426د61","PlaqueCoded":110561426,"PlaqueType":"","SystemType":"سمند","VinNo":"IRFC831V3GJ844131"}
I converted it to UTF8 byte and again convert it to utf8 string but not solved.
The encoded data is in Persian language .
I traced the request in fiddler and i found that the data is come with the correct format as you can see ,But in my code is changed
The WebRequest contains the Encoding property you can set up before downloading the service reply. Details are here: https://msdn.microsoft.com/en-us/library/system.net.webclient.encoding(v=vs.110).aspx
I am trying to find a process by which to edit and write to a resource .rc file; I attempted to use the sample code listed at
How to increment values in resourse file by using vbscript but the last line in both samples returned the same error ( fso.OpenTextFile(rcfile, 2).Write rctext ) :
Error: Invalid procedure call or argument
Code: 800A0005
Source: Microsoft VBScript runtime error
I modified the script to write out to a .txt file and that worked fine, but I'm baffled as to what may be causing the problem writing out to a .rc file.
From the linked sample (simplified)
rctext = fso.OpenTextFile(rcfile).ReadAll
rctext = ....
fso.OpenTextFile(rcfile, 2).Write rctext
The idea is read all the file, and as far as there is no variable holding a reference to the opened file, it is closed, then change what needs to be changed and open again the file, now for writing, and write the changed content to file
And, usually, it works. But sometimes the file opened for reading is not closed fast enough to later open it for writing.
To ensure the file is closed and then can be opened for writing, change the reading code to
set f = fso.OpenTextFile(rcfile)
rctext = f.ReadAll
f.Close
As your line
fso.OpenTextFile(rcfile, 2).Write rctext
does three things (access fso, open file, write to it), there are many things that could go wrong. Please see this answer for ideas wrt to problems concerning the first two actions. Another answer concerns the write.
In your case, the evidence - works with a.txt, but not with b.rc - makes it highly improbable that the file's opening is to blame (so .Close won't save you). I suspect that the .rc contains Unicode (UTF-8/UTF-16) data that the textstream can't encode.
So either use the unicode parameter to read/write open the file with UTF-16 encoding or an ADODB.Stream for UTF-8.
It seems that the answer to my question required both of your answers(#MC ND and #Ekkehard.Horner); also, once I changed the vbs script to open and write to the .rc file in Unicode, which I'm not sure why I have to, the script was able to execute without error.
Here is the vbs script in it's final form:
Const ForReading = 1, ForWriting = 2
Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
Const DoNotCreate = false
rcFile = "C:\Path\To\RC\File.rc"
major = 4
minor = 3
maint = 2
build = 1
version = major & "," & minor & "," & maint & "," & build
Set fso = CreateObject("Scripting.FileSystemObject")
Set fileObj = fso.OpenTextFile(rcFile, ForReading, DoNotCreate, TristateTrue)
rcText = fileObj.ReadAll
fileObj.Close
Set regex = New RegExp
regex.Global = True
regex.Pattern = "(PRODUCTVERSION|FILEVERSION) \d+,\d+,\d+,\d+"
rcText = regex.Replace(rcText, "$1 " & version)
regex.Pattern = "(""(ProductVersion|FileVersion)"",) ""\d+, \d+, \d+, \d+"""
rcText = regex.Replace(rcText, "$1 """ & Replace(version, ",", ", ") & """")
Set fileObj = fso.GetFile(rcFile)
Set textStream = fileObj.OpenAsTextStream(ForWriting, TristateTrue)
textStream.Write rcText
textStream.Close
The only thing that does not seem to work is the regex for replacing the ProduceVersion|FileVersion values, but hopefully I can hammer that out within a reasonable time.
CAtlNavigateData navData;
CStringA m_strForm = "name=+++&priv=1&password=";
navData.SetSocketTimeout(m_nMilliSecond);
navData.SetMethod(ATL_HTTP_METHOD_POST);
navData.SetPostData((BYTE*)(LPSTR)(LPCSTR)m_strForm, m_strForm.GetLength(), QHTTP_FORM_URLENCODE);
I catch the posted package, and find post data
name = "", it should be name="+++". Does SetPostData(...) can not deal with special symbol. How can I avoid this?
Thanks for Snazzer's answer. Does ATL provides API for doing this?
You need to URL encode your string, so replace the '+' with '%2B'
CStringA m_strForm = "name=%2B%2B%2B&priv=1&password=";
For more information, check out URL encoding