yoy.be "Why-o-Why"

freeware

2005-06-10 20:46  freeware  freeware  [permalink]

---Here are a few applications I wrote, a few of them I use myself, a few were just for fun...

They're put public here as FreeWare, some are OpenSource. I haven't figured out yet if I need to put them here under a license or even which one. So for now they're all rights reserved and use em at your risk, though there's really nothing to fear because they really don't do more then they're supposed to do.

Anyway, if you really want to have a look at the SourceCode, let me know -- StijnSanders

(Click on these icons:)

[tx] [TreeBrowse] [DirDiff] [DirFind] [odo] [RE] [jsonDoc] [Connect 4] [CursorTime] [MetaClick] [MetaKeys][BarCode] [MailCount] [Ro] [Fa] [WebTop] [SideSwitch] [Drink]

AllSorts (shell extension)
Growthris
IconSuite
WikiEngine
TortoiseSVN icons
xxm
github.com/stijnsanders

twitter reddit linkedin facebook

xxm v1.2.8.510

2024-01-08 17:48  xxm510  coding delphi freeware  [permalink]

→ xxm v1.2.8.510 (→gh) (→sf)

A quick follow-up release. I've had more reports of xxmHttp*.exe being wrongly identified as a Trojan horse, so I did more work on the code around the LoadLibrary call. (A very big thank you to VirusTotal. But that still doesn't fully guarantee it won't get flagged again now or in the future.)The NT-service versions apparently were broken, so I had to fix that. (And found a few more optimizations along the way!) I've been test-running a few days now and all works smoothly again. So be sure to update in case you've also ran into problems, otherwise nothing functional changed compared to revision 500.

twitter reddit linkedin facebook

tx as a service

2024-01-05 23:43  txsvc  coding delphi freeware  [permalink]

tx "stand alone version" is now available as an NT-service, since I added the files for xxmConv for it. (If you're interested, it's called from here.)
The original tx "stand alone version" was intended as a show-case to see if tx could work for you (and/or your team?), so it would only bind to 'local loop addresses' ('127.0.0.1' for IPv4 and '::1' for IPv6, when available) for security.
But if you like it — and are not planning to do development on tx itself — this service version is what you need. You could install it on a server on the local network, so it's available to your entire team.
If you do want to tinker with tx itself, — it's an open source project after all — you're welcome to install xxm to host tx.xxl you build from source. (Hmm, should add a file with the steps in detail how to do that...)

twitter reddit linkedin facebook

xxm v1.2.8.500

2023-12-29 20:24  xxm500  delphi freeware  [permalink]

→ xxm v1.2.8.500 (→gh) (→sf)

ATTENTION:

Executable files xxmHttp*.exe may get misreported as malware of type Trojan horse ("Trojan:Win32/Bearfoos.A!ml" or "Trojan:Win32/Wacatac.B!ml" or others). Please configure exceptions where appropriate, or post false positive reports to your respective malware-detection-tool-vendor. Feel free to inform me of these cases. I have revised the code around the LoadLibraryW call as I suspect this is the most sensitive bit of code that the xxm handler may have in common with Trojon horse software, but I have no definitive means to be sure.

twitter reddit linkedin facebook

xxm v1.2.7.477

2023-11-09 20:40  xxm474  delphi freeware  [permalink]

→ xxm v1.2.7.477 (→gh) (→sf)

This is a relatively small release, but the NTLM/Negotiate change is too important (for security!) to wait too long with. Also the project entry cache should provide a performance increase in almost all cases. (Strange that I haven't noticed this sooner that this was a weak point!) So, in case you have projects that use NTLM (and ContextString(csAuthUser)) to reliably identify users, It's very, very, warmly advised to switch to "negotiate":true (instead of "ntlm":true), and all should work exactly the same (for longer, and more securely). I considered just using 'negotiate' behind the scenes when "ntlm":true is set, but I deem this distinct enough to make a separate setting and I guess security is a thing we should all be actively vigilant for. So they're both there for now, and a future release could drop NTLM. (Or it could be entirely missing from 2.0...)

Plans for the next release are mainly clean-up, for example deprecating xxmLocal (R.I.P. I.E.), and xxmRun (yes, I once thought people would use xxm from a CD-ROM, register it on auto-run and have the local Internet Explorer serve dynamic web-pages from an xxm project that uses the content from the disc... What was I thinking!). xxmGecko was already deprecated (yes, I once thought people would 'enjoy' — for lack of a better word — URL's in the address bar that start with xxm://... What was I thinking!). With those out of the way I can do some more work on the underlying project entry registry, and have the project on in a good position to leave it for a while and maybe get started on 2.0... We'll see.

Update: there was a "v1.2.7.474" first, but had a bug in TXxmProjectCacheJson.FindProject, which would mingle projects between eachother when hot-reloading xxm.json... Be sure to update if you are running this version.

twitter reddit linkedin facebook

xxm v1.2.6.466

2023-06-05 22:28  xxm466  delphi freeware  [permalink]

It's been quite a while since I've done a release, and I regret that I wasn't able to offer more novelties with this release, but the fixes and improvements do make a solid release. By switching to Delphi Community Edition, I can now provide 32- and 64-bits editions. I have also included 32-bits binaries compiled with Delphi 7, for any case where you need to host (existing?) older *.xxl files and need the exceptions handled. Newer Delphi versions have a binary incompatibility in the exception handling, which either results in exceptions not getting handled correctly, or a new access violation thrown instead by Delphi's internal exception handling. (If you prefer running mixed-delphi-version xxm-handlers and -project-binaries, consider exposing IXxmProjectEvents1 by the project object, and use HandleException to output a suitable message.

Also be advised, if you're updating from v1.2.4 or before, Web.xxmp's will still get converted from XML to JSON. (See the v1.2.5 release notes.)

→ xxm v1.2.6.460 (→gh) (→sf)


twitter reddit linkedin facebook

WinHttpWS.pas: connect to a websocket using winhttp.dll

2023-03-30 23:02  WinHttpWS  coding delphi internet freeware  [permalink]

I needed to fetch something from a WebSocket real quick, but the project didn't have anything like networking components included yet. So I decided a quick-and-easy-way to get to what I needed is using winhttp.dll... I share this hoping it may come in handy for anyone else...

→ Github Gist: WinHttpWS.pas

twitter reddit linkedin facebook

DirDiff v2.0.5.646

2023-03-03 22:51  dirdiff646  coding delphi freeware  [permalink]

DirDiff v2.0.5.646

There was a bug when diff-ing XML files. Incorrect characters were shown when (re-)indenting nested XML elements. I also upgraded the project to Delphi Community Edition version 10.4

twitter reddit linkedin facebook

Eszett: enter ß by typing Ctrl+Alt+S (AltGr+S)

2023-02-23 22:24  eszett  coding delphi freeware  [permalink]

eszett.exe ~2.3MB

When typing German on non-German keyboards, it's not entirely clear how to enter the "ß" character. There's charmap.exe and Win+"." but those are all pretty indirect.
Install eszett.exe to map the combination of Ctrl, Alt and "S" (or 'AltGr' if your keyboards has it, and "S") to enter a "ß" character.

(Source code available here)

twitter reddit linkedin facebook

DIY Google Authenticator

2021-02-25 20:12  diytotp  coding delphi internet freeware  [permalink]

Recently, I've got a few things asking to enable two-factor-authentication, and I started using the Google Authenticator app.

I kind of like it. It's a simple enough app, there's a shared secret involved, but it gets pretty close to being airgapped and perfectly forward secure and all of those things. So I got thinking... What would it take to start using it for myself, in those little software things I create now and then...

Is there black magic or stick whittling involved? Nah, a little searching around, and it all appears to be cleanly described in RFC's 6287 and 4226... There has to be a warning here about not rolling your own crypto, but the world of hashing and encrypting really is interesting! I did SHA1 and HMAC before, and Unix' time apparently is UTC... So all you need* is the correct format of URL to put into a QR-code to load up a new key in the app. Then you can use this code to generate the 'current' pass-code for the secret:

github.com/stijnsanders/tools/.../crypto/totp.pas

*: and apparently base32-encoding, HashUtils was missing that...

twitter reddit linkedin facebook

QuickReports: R.I.P. Lut

2020-12-18 16:26  invoicetemplates  coding delphi werk freeware  [permalink]

→ https://stackoverflow.com/questions/65348138/quickreport-on-delphi-sydney-10-4-1

Oh my, I didn't know. I guess we'll see this more and more with one-person open-source projects, that people stop with the project for all kinds of reasons.

But about reports, I've made this really elegant thing at work to script the design of a report with just a few basic commands (line, text, image, matrix, block, repeat...) that allows you to write what the report should look like, and make lots of small alterations later. If you really need your reports just right, I've always found a graphical designer to introduce minor artefacts that you sometimes need to work around...

I know there are tons of similar things out there, like TeX and PostScript, and even HTML or MetaFiles, but it was grown out of neccessity and suffered "dogfooding" from the very start, which shows in its design and execution. And thanks to SynPDF, (or "Print to PDF" for that matter) you can just exports PDF's with it as well. So I really should take some time and re-do it on my own time and open source it... If I can make it even better and cleaner, I might introduce the open-source version as a replacement at work! (... Oh-oh!) (... or was it this one?)

twitter reddit linkedin facebook

The creator of tx use tx.

2020-08-16 16:09  txdogfood  dagboek freeware  [permalink]

→ Alper: The JIRA team does not use JIRA and of course why would they if anybody gave them the choice.

The creator of tx uses tx.

twitter reddit linkedin facebook

Microsoft Teams was down?

2020-03-16 20:29  nottx  actueel coding computers dagboek delphi werk freeware  [permalink]

→ Microsoft Teams goes down just as Europe logs on to work remotely — Verge

Tx wasn't down, especially the instance you host yourself.

twitter reddit linkedin facebook

Feeder: support WordPress API "wp/v2/posts"

2019-09-14 23:40  wpv2posts  coding delphi internet freeware  [permalink]

Is it normal that a WordPress website serves it full "https://api.w.org/" REST API from the home page (e.g. https://foreignpolicy.com/)?

I just happed to notice <link rel="https://api.w.org/" href="..."> while I was looking for an RSS url. So I had to have a closer look. It looks like it's open for anyone to POST new posts to /wp/v2/posts?!

Anyway, I've created support for it in feeder/eater...

twitter reddit linkedin facebook

A PDF website

2019-07-14 00:54  pdfweb  coding delphi internet freeware  [permalink]

I had an idea. PDF nowadays open right in the same browser window. We can thank the steady progress of the JavaScript ecosystem to make this possible. And also more secure, if I understood correctly.

Also, in a PDF you can mark text or a rectangle as a hyper-link. So it should be possible to create a dynamic website that uses PDF instead of HTML, right? One way of looking at it is that PostScript in PDF is a way to layout things on your page just like HTML is.

Anyway, I had to see how much of work it would take to make a proof-of-concept. So here it is, it's not much on the dynamic side, but it's a site that opens to a PDF, and links to another page of the same site.

https://github.com/stijnsanders/pdfweb

twitter reddit linkedin facebook

jsonDoc v1.2

2019-01-18 08:53  jsondoc12  coding delphi freeware  [permalink]

I don't really know where my open-source/freeware projects get used by other people (and I don't really care all that much, really), but ofcouse where I use my private libraries in the projects of my day job, I've got a first-row seat to see how they perform. No, even better, I'm the stagehand. I know it's important to keep the two separated though. At work I can only use and call libraries, never work on them. I can make changes, but I would have to do so like anybody else: clone a local repository, store the changes there, and when they're ready have the good manners of sending out a pull request. If 'at-home’-‘hobbyist-programmer’-me decides to merge it, it makes my employer a co-creator of the project, creating a new legal situation that my employer would need to know about.

What I can also do, ofcourse, is let private-me know that ‘at-work’-me would really like this or that extra feature or interface, and then when I can put some evening time into programming, I can see if I get round to it. Github issues are nice for that. Or Post-It's on my car key...

But recently I've got a real decent suggestion from a collegue. It didn't come in over a pull request, but it made sense, so why not put it in at the base:

https://github.com/stijnsanders/jsonDoc/commit/fb01e0865fa888c7441234726dc4a90b0c802582 

The IJSONDocument interface has Parse to load data from a string holding JSON data, and a function ToString to convert the contents back to a string. For jsonDoc (and bsonDoc before that) I want concise syntax, so I though I'd make Parse a function that returns Self so you can chain calls. But my collegue wondered why IJSONDocument doesn't have a property AsString:WideString;. In theory it would have read ToString write Parse, except Parse needs to be a procedure, not a function. So I had a close look and changed it around. Another option would be to add an extra procedure SetString, but that would mean the virtual method pointer table for the IJSONDocument interface would have an extra item, to a method with exactly the same behaviour, which makes little sense.

So I changed it around. If you really like/need chaining, there's still the function JSON overload that takes a Variant. If you pass it a string, it'll call plain function JSON to get a new instance, and call Parse for you on the string.

twitter reddit linkedin facebook

NoSQL agent with SQL back-end(s)

2018-12-29 15:41  nosqlidea  coding delphi freeware  [permalink]

It happened again. I get this great idea that slowly develops, and gives the feeling I'm on to something, but nowhere near any time in the forseeable future to put in to it and get a proof-of-concept of a first project that makes it work. So, for what it's worth, I write it down here fast in the hope sharing it with you may give more chance to this idea getting useful.

I've read that some NoSQL solutions are actually about eventual consistency, meaning in the best case of a query for data that was just inserted or updated could already return this new data if the server(farm) ad already fully processed it. Worst case is that it just for a few milliseconds totally disappears, but that's another story altogether.

I haven't done anything serious with NoSQL yet, and really a lot on good old SQL, and recently with SQLite which I've really grown to love in a short period of time. But still there's something there that's really suited for the new style of programming that is going on with all the new web projects and this 'Internet of Things' everything is on about... To find out, I've been trying interfacing with a number of them from Delphi in the most direct way I could possibly find and make work with reasonable effort. I like how TMongoWire worked out, to talk with PostgreSQL all you need is in the libPQ.dll, but a number of others just stick with a plain HTTP API where you PUT and GET things on their own URL. There's a beauty to that, really. The structure of your documents is nicely contained in JSON, and HTTP is such a stable platform you're sure to be able to access it from almost any platform.

So that's where the idea came from: what if I made my own service where you can just put or get JSON documents? But on the back-end jsonDoc would do the heavy lifting and the storage itself could be in a decent SQL service. And/or it could be in something intermediate like memcached. And/or the saving to storage could be asynchronous somewhere close after the actual PUT call (hence the eventual consistency).

For example, you fill a collection of items with things with a number of fields, for example one is "Price", but later you need the items above or below a certain price, you would do SQL "select * from Items where Price<@p". So in this service I'm imagining, there would be meta-description on the collection that you've provided a SQL database somewhere, but the service is responsible for having done the "create table Items (ID some primary key, DATA json, Price decimal(8,2))" and filling it with the data.

And this would be the beauty of it: if you need an extra column later, you just say so, and the connector would be responsible for the "alter table Items add ..." and filling that column with the data from the stored items. Perhaps even slowly, asynchronously together with the other work. Or even another connector alltogether, let's say PostgreSQL and MySQL side by side, perhaps even as a fail-over for eachother.

But I'm dreaming. It would be a load of work just to get something to work, and even more work to get enough connectors to work good enough to even demonstrate how it would work. And then there's the performance trails... And the evangelising to see wether it solves other people's problems anyway... It would be a really great opportinity to finally cut my teeth on this IOCP thing.

twitter reddit linkedin facebook

Update to SQLite 3.26 as soon as possible

2018-12-24 14:52  sqlite326  coding delphi freeware  [permalink]

It's very rare something turns up in the SQLite package, but when it does is best to give it some attention. So, very esteemed users of TSQLite — and anyone else, really — I strongly suggest you upgrade to version 3.26 of sqlite3.dll since recently some dangerous vulnerabilities have been uncovered. I checked, and nothing extensive changed to the API so chances are nothing should break if you only update sqlite3.dll and not SQLite.pas and SQLiteData.pas. Also, happy Christmas!

twitter reddit linkedin facebook

TOML? YAML? ini-files? JSON? Loosen up!

2018-12-10 11:26  jsonloose  coding delphi freeware  [permalink]

TOML? YAML? plain old INI-files? or shiny and new — but strict — JSON? Nàh. I've made myself something better. In jsonDoc.pas I've recently added an optional compiler define JSONDOC_JSON_LOOSE that makes the JSON parser a whole lot genter to work with. Some things are no longer required: the root document doesn't need to start and end with braces ("{}"), the quotes around the key names are no longer required (unless they contain special chars), the comma's between key-value pairs are no longer required, it accepts equal ("=") between keys and values instead of colon (":") and can even do entirely without.

And while I was at it there's also JSONDOC_JSON_PASCAL_STRINGS that allows you to write string literals the Delphi way: between single quotes, and double single quotes where you want a single quote in the string value. This way — really handy in Windows environments — it doesn't require you to escape backslashes.

The only downside maybe is that you need to add the defines to the compiler parameters, but for plain old configuration something like this:

x=5
y=10
output='C:\test\output\'

looks a lot nicer and like what we're used to, and gets parsed just the same as if it was written like this:

{
"x":5,
"y":10,
"output":"C:\\test\\output\\"
}

twitter reddit linkedin facebook

xxm 2.0? About the big plan

2018-11-28 22:50  xxm2plan  coding delphi weblog freeware  [permalink]

Should I begin on xxm v2.0? Delphi having a Community Edition is really really great news, not only for all of the Delphi community, but also for me as a hobbyist programmer with a number of freeware opensource projects out there. Except I was one of those that stuck with Delphi 7 up till now, so next to myself being fully convinced to finally take the step, I also need to have a look project-per-project how to lift them into these modern times and upgrade them to full Delphi 10 projects.

One of my darlings is xxm. You can compile xxm with modern Delphi just fine. I switched string to AnsiString or WideString explicitly nearly everywhere, so you shouldn't get as much as a hint. (Except mayby somwhere where I still have case x in ['A'..'Z'] of or something like that where x is a char and thus is a WideChar, and the compiler doesn't like that). But I'm worried about how I chose to set up the project. I thought I was best to just inherit from IUnknown and define a decent interface and build everything around that. But several xxm projects later, some that are even running some decent production load at work, I learned some things, most importantly these two:

It looks like xxm doesn't need to work with object instances. Requests are coming in, something needs to build a response, but having to have your objects set up first before you can get crackin' now appears as something I should have tried to avoid. Specifics and identities are handled by the underlying communication framework anyway, so you can get by with just a reference, and request more with that reference only just when you need it.

The other is that with the dynamics of IUnknown pointers, you're still dragging this COM thing with you. Yes it may be wafer-thin really and proven tech, but it's still something removing you from what really counts: pointers to where the code is to run. If you're really (really!) pushing to get the last drop of jouce from the orange performance-wise, it may be just that last thing that's in the way. Even when you avoid any locking in reference counting.

So this is the big plan for the moment: if I get to put some decent time into the project, over the next year(s), I'm considering starting a blank project xxm 2.0, start with a plain C style interface with just procedure and function pointers — a really really ancient looking interface — that has everything that IXxmContext and related interfaces have now. Then re-start with xxlProto and xxmHttp to make that work,  then a new xxmCGI, xxmSCGI, xxmISAPI, xxmAhttpd (and perhaps now really a xxmFastCGI, but no xxm IInternetProtocol any more, sorry) and then have a first new push to see how it performs, with IOCP and http pipelining, and who knows HTTP/2 or HTTP/3 that'll have materialized by then.

After that I was thinking I need a new implementation of IXxmContext that just patches through to the new xxm 2.0 calls, so you can very easily and without a worry add it to an existing xxm v1 project and run it with the xxm v2 handlers, enjoy the performance benifits and slowly change things over to xxm v2 where you need to — or not at all, really.

I hope it's a good plan, but for now it's all a dream. I haven't been able to put much time into my hobby projects lately, but it fluctuates and if it picks up some I'll see how far I'll get. Along the way I still hope to find more people that are searching for a good way to combine good old web-scripting with the power and speed of the Delphi compiler, and can count on xxm to offer good debugging, easy live-updating and a stable and secure platform for their web projects.

twitter reddit linkedin facebook

TMongoWire on jsonDoc v1.1.8

2018-11-01 17:24  mwjd118  coding delphi freeware  [permalink]

→ TMongoWire commit 78c7c62: jsonDoc v1.1.8

I may have decoupled the bit that works with structured data (using Variants), and converts to/from JSON, into a separate project jsonDoc, and have converted TMongoWire to run on jsonDoc, I also should take the time to update TMongoWide when jsonDoc gets improvements. The fact is I'm doing much more with JSON than on MongoDB recently, so I risk letting this slip out of sight.

What I also should do is set the TMongoWire repository up so it uses the jsonDoc repository as a git module, but for now it's just about one single file so I'll see when I get to it (...).

twitter reddit linkedin facebook

RSS is far from dead!

2018-08-08 00:55  feeder  delphi internet freeware  [permalink]

I've been using RSS/Atom feeds on and off since I've learned about them. A long time ago, Google had a nice feed reader, but decided to discontinue it. Users were left to search something new, and I settled on The Old Reader, combined with gReader since I had a smartphone, and all was well. For a while. After some time you notice you still get disturbed by some tiny issues you can't seem to get to go away, either with tweaking the configuration or with Stylus. So what does a developer do? Start to think about developing their own solution. Then plan to develop their own solution. Then develop their own solution. So I'm somewhat proud to present this little thing I've been tinkering on in off-hours the last month:

github.com/stijnsanders/feeder

I have a live version to try out here: http://yoy.be/home/feeder/ but it uses the neighbouring instance of tx for authentication. I should enable Google/Facebook/Github OAuth things instead, but finding out how that works is a few items lower on my wish-list (of things I wished I had the time to put into).

I wanted a feed reader without the extra's. I wanted to mark items as read that move out of view by scrolling down, and plays somewhat nice with the surrounding HTML and the browser. For now I like how it works. There's an issue with emoji's that apparently get eaten by UTF8Decode, but that could be a bug that got solved since good old Delphi 7. But now that Delphi has a community edition, I think I should bring most if not all of my other projects to this version instead of sticking to Delphi 7... But that's another story. (One you might notice some time in the future on my Delphi RSS feed...)

twitter reddit linkedin facebook

DirDiff v2.0.4.535

2018-06-23 00:31  dirdiff535  freeware  [permalink]

DirDiff v2.0.4.535

There was a bug when diff-ing more than 2 files or folders, where lines matching between other files than the first/left one would show as matched.

twitter reddit linkedin facebook

AES v1.0.1

2018-05-21 20:18  aes101  coding delphi freeware  [permalink]

md5

I noticed something was wrong with the key generation schedule in my AES implementation. I had a close look with the FIPS 197 example vectors at hand and fixed it. I still should make some time to run it under pressure and see how it relates to reference implementations and popular implementations.

twitter reddit linkedin facebook

xxm v1.2.5.450

2018-05-03 22:43  xxm450  delphi freeware  [permalink]

For a while I thought there's not enough there to have a full release, but with the switch from XML to JSON, and NTLM and WebSocket support in xxmHttp and xxmHSys2, plus all the minor changes and tweaks that improve performance and security, it turns out to be quite a formidable release. Regretfully, by finally deciding to have all string arguments const anyway, any project's xxmp.pas will have to change. A long time I was hesitant about this because I feared binary incompatibilities, but I've tested all permutations between caller/called with/without const, and it all works. Except when building old code with the new xxm.pas will serve you with this minor one-time inconvenience of having to add const yourself to the arguments... I've thought about trying to create something automatic — like the XML to JSON converters — but since you're quite free to modify xxmp.pas to your liking, it may be more complex than it seems. (If you would like to see this anyway, let me know and I'll put some time into that.)

It's advised to do an extensive test-run with this new version before you update the live environment. If anything unexpected turns up, let me know!

xxm v1.2.5.450 (→gh) (→sf)


twitter reddit linkedin facebook

What do you think I should do?

2018-04-20 23:26  sendfile404  delphi freeware  [permalink]

Dilemma, dilemma! What should I do? Sometimes, you need to have a certain URL in a web-project that just serves op the contents of a local file. You could try to have the file in a static section of the website, or even a sub-domain for static content (if your budget allows it), but then it's out there for anyone. Best is to have a request be processed dynamically, so you can do some server-side logic first, for example to do authentication control, or generate the file first (perhaps with a graphics library?). That's where the SendFile method of the IXxmContext comes in. The code that implements it is pretty straight-forward: 

procedure TXxmGeneralContext.SendFile(const FilePath: WideString);
begin
inherited;
if State=ctHeaderNotSent then FSingleFileSent:=FilePath;
SendStream(TStreamAdapter.Create(TFileStream.Create(FilePath,fmOpenRead or fmShareDenyNone),soOwned));
end;

If the request's header has not been sent already, the private value FSingleFileSent is set to the file path, assuming the request is meant to have this file's data as response data. This is used for error handling and logging.

Then SendStream is called, which takes an IStream pointer, so a TStreamAdapter is used to wrap around a TFileStream, with ownership so the last IStream._Release will call the file stream's destructor.

One thing that's missing here perhaps is trying to figure out if the HTTP response header Content-Type is set to some suitable MIME-type for the file, but this is so untrivial that it's best left to the developer. So give it a second of thought when you're coding a call to SendFile.

So about this dilemma I'm having. Just imagine for a second you have this code in a project. Attention: this is very bad practice! It should be glaringly obvious to everybody that doing this opens the back door wide open and people with malicious intent can access any file they want on the machine, include system files, so please don't ever really do this:

[[Context.SendFile(Context['f'].Value);]]

Yikes. Very very bad! I feel dirty just for typing that, but just as an example, this code has a high probability of trying to open a file that doesn't exist, or otherwise have the TFileStream.Create throw an EFOpenError exception.

In that case, would it be better if xxm answers with a proper HTTP 404 (page not found) response? Now default exception handling kicks in, and left unhandled (hint) xxm will fashion a HTTP 500 response for you with the exception data. There's also a bit that will see if your local fragment registry can load a fragment for '404.xxm' that lets you design a nicer 'page not found' page than the default, but I'm having a hard time to guess if that would be something unexpected for someone somewhat new to xxm, calling SendFile on an inexistant file for the first time...

I'd love to hear from anyone on this, but for now I'll just let it be like this and let the normal exception play out, if any.

But wait, there's more. Deep burried within the dark corners of the Windows API, there's a thing called TransferFile. It basically lets you tell the system to take a file handle and a network handle and stream all the data from the one to the other, as much as possible right from the kernel. The way the friendly people over at Microsoft worked it out, and tied it to the running system so it would only work on Windows Server versions, makes it kind of unsuitable for where I want to take the xxm project.

But wait, there's more. You may have noticed the web-sphere is gripped with a frenzy for all things asynchronous. There are a few good things there, but it is mainly the best way to serve a magnitude more of concurrent requests by the same server. The short story is you try to avoid waiting on the system while it waits on network or disk. The long story envolves completion ports or libuv, but is in essence unfit to combine with what xxm is doing: having a separate DLL with code you just call to have a response generated for a request, since to do it properly every request to the operating system needs to be re-routed over your job/thread/task/fiber/yarn-management.

This shouldn't hold me back to get as close as possible to the middle ground between the two, where you have the option to build a response, but can hand over a (file)stream and have the HTTP server spool that as it sees fit,  once the situation really is just that straightforward. But this may be what xxm 2.0 could be about, if there ever will be something like that.

twitter reddit linkedin facebook

 

Archive... Search...