I really like development in Visual Studio even if I have a feature to implement for other platforms. And anytime I can I try to continue this experience. Period.
This time I had a pleasure to wrap several HTTPS calls using libcurl. But how to make it run on my x64 Windows machine? There is some info on StackOverflow.com, what can be moved to VS2017 in following steps:
- Start VS2017 console: "%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
- Download the curl-7.53.1.zip source-code and unzip it
- enter “winbuild” folder
- compile with Windows SSL build-in support: nmake /f Makefile.vc mode=static VC=14 ENABLE_IPV6=no MACHINE=AMD64(optionally mode can be set as ‘dll’ to have later one more DLL do deal with in the project)
- grab the outcomes from “/builds/libcurl-vc14-AMD64-release-static-sspi-winssl” folder
- setup new project’s ‘include’ and ‘lib’ folder (put libcurl_a.lib or libcurl.lib into references)
- and remember to take a look at samples!
Lastly I have shown how to enforce encoding of strings in DBF table by setting up code-page inside its header. I also mentioned it was the easiest way. That’s still true. But sometimes there is no room to be polite and things need to be done little messy in the code (for example when the DBF file is often recreated by 3rd-party tool an can be altered in any way). So each time the string value is loaded try to recover it with those steps.
First get the original bytes stored from loaded *text* (assume that system inappropriately returned Windows-1250 encoded string):
var bytes = Encoding.GetEncoding("Windows-1250").GetBytes(text);
Secondly convert them from correct encoding (it was natively stored as Latin-2 aka CP-852) to UTF-8:
var convertedBytes = Encoding.Convert(Encoding.GetEncoding(852), Encoding.UTF8, bytes);
Of course encoding objects can be cached to increase performance.
Recently I had a problem importing data from a 10-years-old set of DBF tables. All was fine until it came to reading texts with polish diacritic marks. It worked fine on 9 out of 10 machines, all with identical configurations (or at least I had hoped they are identical and couldn’t find any differences - Windows 7 x64 PL, .NET 4.5.2, the same regional options). On that single one all special letters got converted into some eye-hurting characters and looked purely wrong.
As it started to reveal, the OleDbConnection class I used to connect (with “Microsoft.Jet.OLEDB.4.0” provider) magically treated strings as Windows-1250 encoded, event though they were CP852 Latin-2. Thanks to this site, helping me to find out about it.
I tried to enforce the encoding by updating 0x1D byte of the DBF header with proper code page. Following is the list of all possible values (I used 0x64), but still it didn’t help much.
|0x00||No codepage defined|
|0x01||Codepage 437 (US MS-DOS)|
|0x02||Codepage 850 (International MS-DOS)|
|0x03||Codepage 1252 Windows ANSI|
|0x04||Codepage 10000 Standard MacIntosh|
|0x64||Codepage 852 Easern European MS-DOS|
|0x65||Codepage 866 Russian MS-DOS|
|0x66||Codepage 865 Nordic MS-DOS|
|0x67||Codepage 861 Icelandic MS-DOS|
|0x68||Codepage 895 Kamenicky (Czech) MS-DOS|
|0x69||Codepage 620 Mazovia (Polish) MS-DOS|
|0x6A||Codepage 737 Greek MS-DOS (437G)|
|0x6B||Codepage 857 Turkish MS-DOS|
|0x78||Codepage 950 Chinese (Hong Kong SAR, Taiwan) Windows|
|0x79||Codepage 949 Korean Windows|
|0x7A||Codepage 936 Chinese (PRC, Singapore) Windows|
|0x7B||Codepage 932 Japanese Windows|
|0x7C||Codepage 874 Thai Windows|
|0x7D||Codepage 1255 Hebrew Windows|
|0x7E||Codepage 1256 Arabic Windows|
|0x96||Codepage 10007 Russian MacIntosh|
|0x97||Codepage 10029 MacIntosh EE|
|0x98||Codepage 10006 Greek MacIntosh|
|0xC8||Codepage 1250 Eastern European Windows|
|0xC9||Codepage 1251 Russian Windows|
|0xCA||Codepage 1254 Turkish Windows|
|0xCB||Codepage 1253 Greek Windows|
|all others||Unknown / invalid|
Ultimately, the very old Visual FoxPro driver did the trick (with switched provider to “VFPOLEDB.1”) and respected encoding, saving me from manual strings transcoding in my C# application.
Now you have seen everything!
In my recent post I have shown, how to track web requests issued against remote server I don’t have a control over. Curious reader could ask at this point – but what have I broken this time? And the answer is as usual – personally did nothing wrong, I was just doing my job. I had to port some HTTP related code from using Windows Runtime-specific HttpClient (i.e. Windows.Web.Http.HttpClient) to also work outside the sandbox on a regular .NET 4.5 desktop version and start using System.Net.Http.HttpClient instead.
Then I noticed that everything worked fine except multipart form-data submissions using POST method that were behaving unexpectedly bad (timeouting or returning an error immediately). There was nothing unusual mentioned on MSDN, so I started to compare sent requests using both implementation. It turned-out of course, the problem lied deeper in the framework in a value serialized as a *boundary* part of the Content-Type field. HttpClient from the System.Net.Http somehow was adding extra quotes around it, while the one from Windows.Web.Http didn’t. Even though server should accept both values (according to RFC2046 section 5.1.1), it actually didn’t and was waiting for correct *boundary*.
Simple fix by manually overwriting the guilty header can look like that:
var request = new HttpRequestMessage(HttpMethod.Post, url);
var boundary = "--" + Guid.NewGuid().ToString("D");
request.Content = new MultipartFormDataContent(boundary);
// fill content
// update the Content-Type header to be accepted by the server:
request.Content.Headers.TryAddWithoutValidation("Content-Type", "multipart/form-data; boundary=" + boundary);
// send request:
var result = await _client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token);
World saved. Job done!
Usually it’s not a big deal, when a HTTP request to a remote server is not working on a desktop Windows machine. There are plenty of useful tools, that could help in the process:
- one, which work like a proxy and dump the whole traffic, that we might be interested in (Fiddler would be the best example here)
- others, that interact with the TCP/IP stack itself and look much deeper for sent packets (like WireShark or Microsoft Message Analyzer).
BTW. Do you know, that there is a way to visualize HTTP traffic in Fiddler, that was originally captured by Wireshark or MMA?
Simply export packets from WireShark as pcap file (File –> Export –> Export as .pcap file) and import it directly into Fiddler (File –> Import Session… –> Packet Capture).
Many thanks to Rick Stahl, for showing me this feature.
Mobiles are totally different world. Mostly because applications are running in a dedicated sandbox and there isn’t at all internal or external access on system level. There is not much to do beside debugging of our own code. But if this doesn’t help, it doesn’t mean we stay blind. Take a look at http://httpbin.org/ (project sources available on GitHub). It’s the server you always wanted to write yourself – server that returns info about client accompanied by a list of headers, info about content for all kinds of submitted requests and even some random binary data, if you like. Respective behavior is selected by dedicated path on the httbin.org server and response is of course in JSON format (maybe beside for the binary data request).
Typically request paths:
- /delete – all of them to know, how the request really looks like
- /status/<code> – to verify, if the application handles given error respectively
- /stream-bytes/<size> – both to download some random binary block of bytes from server.
It *won’t* simulate your destination server at all nor any more advanced interactions. And you will need to to hack your application to be able to issue requests against this server and dump somewhere the JSON response. Still remember, it’s only during application development and while fighting with a non-working request against remote server you totally have no control over, so additional #ifdef won’t hurt at all ;)
Final thought – the trick described above could be also without any problem used inside desktop or Windows Store application. It’s not only dedicated to mobiles!