LCOV - code coverage report
Current view: top level - bin/testrunner - main.c (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 102 127 80.3 %
Date: 2023-04-18 16:19:03 Functions: 9 11 81.8 %

          Line data    Source code
       1             : /*
       2             :  * lwan - web server
       3             :  * Copyright (c) 2012 L. A. F. Pereira <l@tia.mat.br>
       4             :  *
       5             :  * This program is free software; you can redistribute it and/or
       6             :  * modify it under the terms of the GNU General Public License
       7             :  * as published by the Free Software Foundation; either version 2
       8             :  * of the License, or any later version.
       9             :  *
      10             :  * This program is distributed in the hope that it will be useful,
      11             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :  * GNU General Public License for more details.
      14             :  *
      15             :  * You should have received a copy of the GNU General Public License
      16             :  * along with this program; if not, write to the Free Software
      17             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
      18             :  */
      19             : 
      20             : #define _GNU_SOURCE
      21             : #include <stdlib.h>
      22             : #include <unistd.h>
      23             : 
      24             : #include "lwan-private.h"
      25             : 
      26          87 : LWAN_HANDLER(quit_lwan)
      27             : {
      28          87 :     exit(0);
      29             :     return HTTP_OK;
      30             : }
      31             : 
      32           0 : LWAN_HANDLER(gif_beacon)
      33             : {
      34             :     /*
      35             :      * 1x1 transparent GIF image generated with tinygif
      36             :      * http://www.perlmonks.org/?node_id=7974
      37             :      */
      38             :     static const unsigned char gif_beacon_data[] = {
      39             :         0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0x90,
      40             :         0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xF9, 0x04,
      41             :         0x05, 0x10, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x01,
      42             :         0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x04, 0x01
      43             :     };
      44             : 
      45           0 :     response->mime_type = "image/gif";
      46           0 :     lwan_strbuf_set_static(response->buffer, (char*)gif_beacon_data, sizeof(gif_beacon_data));
      47             : 
      48           0 :     return HTTP_OK;
      49             : }
      50             : 
      51           1 : LWAN_HANDLER(test_chunked_encoding)
      52             : {
      53             :     int i;
      54             : 
      55           1 :     response->mime_type = "text/plain";
      56             : 
      57           1 :     lwan_strbuf_printf(response->buffer, "Testing chunked encoding! First chunk\n");
      58           1 :     lwan_response_send_chunk(request);
      59             : 
      60          12 :     for (i = 0; i <= 10; i++) {
      61          11 :         lwan_strbuf_printf(response->buffer, "*This is chunk %d*\n", i);
      62          11 :         lwan_response_send_chunk(request);
      63             :     }
      64             : 
      65           1 :     lwan_strbuf_printf(response->buffer, "Last chunk\n");
      66           1 :     lwan_response_send_chunk(request);
      67             : 
      68           1 :     return HTTP_OK;
      69             : }
      70             : 
      71           0 : LWAN_HANDLER(test_server_sent_event)
      72             : {
      73             :     int i;
      74             : 
      75           0 :     for (i = 0; i <= 10; i++) {
      76           0 :         lwan_strbuf_printf(response->buffer, "Current value is %d", i);
      77           0 :         lwan_response_send_event(request, "currval");
      78             :     }
      79             : 
      80           0 :     return HTTP_OK;
      81             : }
      82             : 
      83          10 : LWAN_HANDLER(test_proxy)
      84             : {
      85          10 :     struct lwan_key_value *headers = coro_malloc(request->conn->coro, sizeof(*headers) * 2);
      86          10 :     if (UNLIKELY(!headers))
      87           0 :         return HTTP_INTERNAL_ERROR;
      88             : 
      89          10 :     char *buffer = coro_malloc(request->conn->coro, INET6_ADDRSTRLEN);
      90          10 :     if (UNLIKELY(!buffer))
      91           0 :         return HTTP_INTERNAL_ERROR;
      92             : 
      93          10 :     headers[0].key = "X-Proxy";
      94          10 :     headers[0].value = (char*) lwan_request_get_remote_address(request, buffer);
      95          10 :     headers[1].key = NULL;
      96          10 :     headers[1].value = NULL;
      97             : 
      98          10 :     response->headers = headers;
      99             : 
     100          10 :     return HTTP_OK;
     101             : }
     102             : 
     103           1 : LWAN_HANDLER(test_post_will_it_blend)
     104             : {
     105             :     static const char type[] = "application/json";
     106             :     static const char request_body[] = "{\"will-it-blend\": true}";
     107             :     static const char response_body[] = "{\"did-it-blend\": \"oh-hell-yeah\"}";
     108             :     const struct lwan_value *content_type =
     109           1 :         lwan_request_get_content_type(request);
     110           1 :     const struct lwan_value *body = lwan_request_get_request_body(request);
     111             : 
     112           1 :     if (!content_type->value)
     113           0 :         return HTTP_BAD_REQUEST;
     114           1 :     if (content_type->len != sizeof(type) - 1)
     115           0 :         return HTTP_BAD_REQUEST;
     116           1 :     if (memcmp(content_type->value, type, sizeof(type) - 1) != 0)
     117           0 :         return HTTP_BAD_REQUEST;
     118             : 
     119           1 :     if (!body->value)
     120           0 :         return HTTP_BAD_REQUEST;
     121           1 :     if (body->len != sizeof(request_body) - 1)
     122           0 :         return HTTP_BAD_REQUEST;
     123           1 :     if (memcmp(body->value, request_body, sizeof(request_body) - 1) != 0)
     124           0 :         return HTTP_BAD_REQUEST;
     125             : 
     126           1 :     response->mime_type = type;
     127           1 :     lwan_strbuf_set_static(response->buffer, response_body,
     128             :                            sizeof(response_body) - 1);
     129             : 
     130           1 :     return HTTP_OK;
     131             : }
     132             : 
     133           5 : LWAN_HANDLER(test_post_big)
     134             : {
     135             :     static const char type[] = "x-test/trololo";
     136           5 :     size_t i, sum = 0;
     137             :     const struct lwan_value *content_type =
     138           5 :         lwan_request_get_content_type(request);
     139           5 :     const struct lwan_value *body = lwan_request_get_request_body(request);
     140             : 
     141           5 :     if (!content_type->value)
     142           0 :         return HTTP_BAD_REQUEST;
     143           5 :     if (content_type->len != sizeof(type) - 1)
     144           0 :         return HTTP_BAD_REQUEST;
     145           5 :     if (memcmp(content_type->value, type, sizeof(type) - 1) != 0)
     146           0 :         return HTTP_BAD_REQUEST;
     147             : 
     148      222225 :     for (i = 0; i < body->len; i++)
     149      222220 :         sum += (size_t)body->value[i];
     150             : 
     151           5 :     response->mime_type = "application/json";
     152           5 :     lwan_strbuf_printf(response->buffer, "{\"received\": %zu, \"sum\": %zu}",
     153           5 :                        body->len, sum);
     154             : 
     155           5 :     return HTTP_OK;
     156             : }
     157             : 
     158         390 : LWAN_HANDLER(hello_world)
     159             : {
     160             :     struct lwan_key_value *iter;
     161             :     static struct lwan_key_value headers[] = {
     162             :         { .key = "X-The-Answer-To-The-Universal-Question", .value = "42" },
     163             :         { NULL, NULL }
     164             :     };
     165         390 :     response->headers = headers;
     166         390 :     response->mime_type = "text/plain";
     167             : 
     168         390 :     request->flags |= RESPONSE_INCLUDE_REQUEST_ID;
     169             : 
     170         390 :     const char *name = lwan_request_get_query_param(request, "name");
     171         390 :     if (name)
     172         276 :         lwan_strbuf_printf(response->buffer, "Hello, %s!", name);
     173             :     else
     174         114 :         lwan_strbuf_set_static(response->buffer, "Hello, world!", sizeof("Hello, world!") -1);
     175             : 
     176         390 :     const char *dump_vars = lwan_request_get_query_param(request, "dump_vars");
     177         390 :     if (!dump_vars)
     178         367 :         goto end;
     179             : 
     180          23 :     lwan_strbuf_append_strz(response->buffer, "\n\nCookies\n");
     181          23 :     lwan_strbuf_append_strz(response->buffer, "-------\n\n");
     182             : 
     183          26 :     LWAN_ARRAY_FOREACH(lwan_request_get_cookies(request), iter) {
     184           3 :         lwan_strbuf_append_printf(response->buffer,
     185             :                     "Key = \"%s\"; Value = \"%s\"\n", iter->key, iter->value);
     186             :     }
     187             : 
     188          23 :     lwan_strbuf_append_strz(response->buffer, "\n\nQuery String Variables\n");
     189          23 :     lwan_strbuf_append_strz(response->buffer, "----------------------\n\n");
     190             : 
     191          69 :     LWAN_ARRAY_FOREACH(lwan_request_get_query_params(request), iter) {
     192          46 :         lwan_strbuf_append_printf(response->buffer,
     193             :                     "Key = \"%s\"; Value = \"%s\"\n", iter->key, iter->value);
     194             :     }
     195             : 
     196          23 :     if (lwan_request_get_method(request) == REQUEST_METHOD_POST) {
     197           1 :         lwan_strbuf_append_strz(response->buffer, "\n\nPOST data\n");
     198           1 :         lwan_strbuf_append_strz(response->buffer, "---------\n\n");
     199             : 
     200           3 :         LWAN_ARRAY_FOREACH(lwan_request_get_post_params(request), iter) {
     201           2 :             lwan_strbuf_append_printf(response->buffer,
     202             :                         "Key = \"%s\"; Value = \"%s\"\n", iter->key, iter->value);
     203             :         }
     204             :     }
     205             : 
     206          23 :     const char *dump_request_id = lwan_request_get_query_param(request, "dump_request_id");
     207          23 :     if (dump_request_id && streq(dump_request_id, "1")) {
     208          20 :         lwan_strbuf_append_printf(response->buffer, "\nRequest ID: <<%016lx>>",
     209             :                                   lwan_request_get_id(request));
     210             :     }
     211             : 
     212           3 : end:
     213         390 :     return HTTP_OK;
     214             : }
     215             : 
     216           1 : LWAN_HANDLER(sleep)
     217             : {
     218           1 :     const char *ms_param = lwan_request_get_query_param(request, "ms");
     219             :     uint64_t ms;
     220             : 
     221           1 :     if (!ms_param)
     222           0 :         return HTTP_INTERNAL_ERROR;
     223             : 
     224           1 :     ms = (uint64_t)parse_long(ms_param, 0);
     225           1 :     response->mime_type = "text/plain";
     226             : 
     227           1 :     if (ms) {
     228             :         struct timespec t1, t2;
     229             :         int64_t diff_ms;
     230             : 
     231           1 :         clock_gettime(CLOCK_MONOTONIC, &t1);
     232             : 
     233           1 :         lwan_request_sleep(request, ms);
     234             : 
     235           1 :         clock_gettime(CLOCK_MONOTONIC, &t2);
     236           1 :         diff_ms = (t2.tv_sec - t1.tv_sec) * 1000;
     237           1 :         diff_ms += (t2.tv_nsec - t1.tv_nsec) / 1000000;
     238             : 
     239           1 :         lwan_strbuf_printf(response->buffer,
     240             :                            "Returned from sleep. diff_ms = %"PRIi64, diff_ms);
     241             :     } else {
     242           0 :         lwan_strbuf_set_staticz(response->buffer, "Did not sleep");
     243             :     }
     244             : 
     245           1 :     return HTTP_OK;
     246             : }
     247             : 
     248           2 : LWAN_HANDLER(custom_header)
     249             : {
     250           2 :     const char *hdr = lwan_request_get_query_param(request, "hdr");
     251             : 
     252           2 :     if (!hdr)
     253           0 :         return HTTP_NOT_FOUND;
     254             : 
     255           2 :     const char *val = lwan_request_get_header(request, hdr);
     256           2 :     if (!val)
     257           1 :         return HTTP_NOT_FOUND;
     258             : 
     259           1 :     response->mime_type = "text/plain";
     260           1 :     lwan_strbuf_printf(response->buffer, "Header value: '%s'", val);
     261           1 :     return HTTP_OK;
     262             : }
     263             : 
     264             : int
     265          87 : main()
     266             : {
     267             :     struct lwan l;
     268             : 
     269          87 :     lwan_init(&l);
     270          87 :     lwan_main_loop(&l);
     271           0 :     lwan_shutdown(&l);
     272             : 
     273           0 :     return EXIT_SUCCESS;
     274             : }

Generated by: LCOV version 1.15-2-gb9d6727