ksgi
/
tutorial3.xml
98 строк · 4.0 Кб
1<article data-sblg-article="1" data-sblg-tags="tutorial" itemscope="itemscope" itemtype="http://schema.org/BlogPosting">2<header>3<h2 itemprop="name">4Custom Validation
5</h2>6<address itemprop="author"><a href="https://kristaps.bsd.lv">Kristaps Dzonsons</a></address>7<time itemprop="datePublished" datetime="2016-08-19">19 August, 2016</time>8</header>9<p>10<aside itemprop="about">11Applications often need to validate more then doubles, integers, or strings included in
12<a href="kvalid_string.3.html">kvalid_string(3)</a>.13In this tutorial, I'll provide some examples on how to override the validation function.
14</aside>15</p>16<p>17The most common validations for uploaded data seem to be JPG and PNG—just enough to make sure that the image really is one18of the two, and won't crash horribly in the main application when being parsed.
19Given that <a href="kvalid_string.3.html">kvalid_string(3)</a> only covers common types, how do we handle custom validation?20Let's consider all three types, using the common
21<a href="https://libgd.github.io/">libgd</a> library to abstract image handling.22</p>23<h3>24Source Code
25</h3>26<p>27We could parse directly using <a href="http://www.libpng.org/pub/png/libpng.html">libpng</a> and so on, but for the sake of our28example, this is a bit easier.
29Our mission is to make sure that a JPG or PNG file is readable.
30In our example, we'll create validation functions, register them with a named input field, then access the parsed data in our
31web application.
32</p>33<p>34To do so, we override the validator as described in <a href="khttp_parse.3.html">khttp_parse(3)</a> (scan down to <q>valid</q>).35It notes that the <code>KPAIR_DOUBLE</code>, <code>KPAIR_STRING</code>, and <code>KPAIR_DOUBLE</code> are provided for36validators that set the <code>parsed</code> field of <code>struct kpair</code>.37However, if our validator sets <code>KPAIR__MAX</code>, we don't use the <code>parsed</code> field at all.38The return code of the function will tell whether to bucket the pair in <code>fieldmap</code> (success) or39<code>fieldnmap</code> (failure).40The web application will then need to <q>know</q> to use the <code>val</code> and <code>valsz</code> if the validated pair41instead of the parsed fields.
42</p>43<p>44To wit, we'll need to create the following functions, with the given header file:
45</p>46<figure class="sample">47<pre class="prettyprint linenums">#include <gd.h>48int
49kvalid_png(struct kpair *kp)
50{
51gdImagePtr im;
52int rc;
53im = gdImageCreateFromPngPtr(kp->valsz, kp->val);
54if ((rc = (im != NULL)))
55gdImageDestroy(im);
56kp->type = KPAIR__MAX;
57return rc;
58}
59
60int
61kvalid_jpeg(struct kpair *kp)
62{
63gdImagePtr im;
64int rc;
65im = gdImageCreateFromJpegPtr(kp->valsz, kp->val);
66if ((rc = (im != NULL)))
67gdImageDestroy(im);
68kp->type = KPAIR__MAX;
69return rc;
70}</pre>71</figure>72<p>73Now we need to hook these into validations.
74Let's assume that our HTML inputs are called <q>jpeg</q> and <q>png</q>, for simplicity.75</p>76<figure class="sample">77<pre class="prettyprint linenums">enum key {78KEY_JPEG,
79KEY_PNG,
80KEY__MAX
81};
82
83static const struct kvalid keys[KEY__MAX] = {
84{ kvalid_jpeg, "jpeg" }, /* KEY_JPEG */
85{ kvalid_png, "png" }, /* KEY_PNG */
86};</pre>87</figure>88<p>89That's it!
90Now, our application logic can simply check for the existence of KEY_JPEG or KEY_PNG in the <code>fieldmap</code> table of91<code>struct kreq</code>, and be guaranteed that the results will be usable (at least by <a92href="https://libgd.github.io">libgd</a>).93The <code>valid</code> interface can do all sorts of more complicated things—for example, we could have converted JPEGs,94TIFFs, and other formats all into PNG files during validation by reading into a <code>gdImagePtr</code>, then writing the95results of <code>gdImagePngPtr</code> into the <code>val</code> and <code>valsz</code> members.96These would then be written into the validated data, and all of our images would then be PNG.
97</p>98</article>99