src/server/admin/admin.c

Wed, 27 Nov 2024 23:00:07 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 27 Nov 2024 23:00:07 +0100
changeset 563
6ca97c99173e
parent 258
134279e804b6
permissions
-rw-r--r--

add TODO to use a future ucx feature

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2013 Olaf Wintermann. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "admin.h"
#include "../util/pblock.h"

#include "../config/conf.h"
#include "../config/objconf.h"

static Page *root_page;

int admin_init(pblock *pb, Session *sn, Request *rq) {
    log_ereport(LOG_VERBOSE, "admin-init");
    pool_handle_t *pool = pool_create();
    root_page = admin_page_create(pool, NULL, admin_root);
    
    Page *ls_page = admin_page_create(pool, "listener", adm_listener);
    admin_add_page(root_page, ls_page);
    Page *cfgls_page = admin_page_create(pool, NULL, adm_cfglistener);
    admin_add_page(ls_page, cfgls_page);
    
    Page *auth_page = admin_page_create(pool, "auth", adm_auth);
    admin_add_page(root_page, auth_page);
    
    return REQ_PROCEED;
}

int admin_service(pblock *pb, Session *sn, Request *rq) {
    pblock_removekey(pb_key_content_type, rq->srvhdrs);
    pblock_nvinsert("content-type", "text/plain", rq->srvhdrs);
    protocol_status(sn, rq, 200, NULL);
    http_start_response(sn, rq);
    
    char *uri = pblock_findkeyval(pb_key_uri, rq->reqpb);
    uri++;
    uri = strchr(uri, '/');
    size_t uri_len = uri ? strlen(uri) : 0;
    // start with second character to skip leading '/'
    int s = 0;
    int i = 1;
    Page *page = root_page;
    for(;i<=uri_len;i++) {
        char c = uri[i];
        if(c == '/' || c == '\0') {
            if(i-s > 1) {
                // we have the path element name
                char *name = uri+s+1;
                size_t name_len = i-s-1;
                
                // get matching admin page
                Page *child = page->children;
                page = NULL;
                while(child) {
                    if(child->name) {
                        if(!strncmp(child->name, name, name_len)) {
                            page = child;
                            break;
                        }
                    } else {
                        page = child;
                        break;
                    }
                    child = child->next;
                }
                
                if(!page) {
                    break;
                }
                
                s = i;
            }
        }
    }
    
    // service admin page
    if(page) {
        AdminRequest arq;
        arq.sn = sn;
        arq.rq = rq;
        page->service(page, &arq);
    } else {
        net_printf(sn->csd, "page not found\n");
    }
    
    return REQ_PROCEED;
}

int admin_root(Page *page, AdminRequest *rq) {
    return REQ_PROCEED;
}

int adm_listener(Page *page, AdminRequest *rq) {
    SYS_NETFD out = rq->sn->csd;
    
    
    
    return REQ_PROCEED;
}

int adm_cfglistener(Page *page, AdminRequest *rq) {
    printf("adm_cfglistener\n");
    return REQ_PROCEED;
}

int adm_auth(Page *page, AdminRequest *rq) {
    printf("adm_auth\n");
    return REQ_PROCEED;
}


// public admin API

Page* admin_page_create(pool_handle_t *pool, char *name, admin_service_f f) {
    Page *p = pool_malloc(pool, sizeof(Page));
    ZERO(p, sizeof(Page));
    if(name) {
        p->name = pool_strdup(pool, name);
    }
    p->service = f;
    return p;
}

void admin_add_page(Page *parent, Page *child) {
    child->parent = parent;
    Page *ch = parent->children;
    if(ch) {
        while(ch->next) {
            ch = ch->next;
        }
        ch->next = child;
    } else {
        parent->children = child;
    }
}

mercurial