⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ncbi_connutil.c

📁 ncbi源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * =========================================================================== * PRODUCTION $Log: ncbi_connutil.c,v $ * PRODUCTION Revision 1000.3  2004/04/12 17:06:12  gouriano * PRODUCTION PRODUCTION: UPGRADED [CATCHUP_003] Dev-tree R6.64 * PRODUCTION * =========================================================================== *//*  $Id: ncbi_connutil.c,v 1000.3 2004/04/12 17:06:12 gouriano Exp $ * =========================================================================== * *                            PUBLIC DOMAIN NOTICE *               National Center for Biotechnology Information * *  This software/database is a "United States Government Work" under the *  terms of the United States Copyright Act.  It was written as part of *  the author's official duties as a United States Government employee and *  thus cannot be copyrighted.  This software/database is freely available *  to the public for use. The National Library of Medicine and the U.S. *  Government have not placed any restriction on its use or reproduction. * *  Although all reasonable efforts have been taken to ensure the accuracy *  and reliability of the software and data, the NLM and the U.S. *  Government do not and cannot warrant the performance or results that *  may be obtained by using this software or data. The NLM and the U.S. *  Government disclaim all warranties, express or implied, including *  warranties of performance, merchantability or fitness for any particular *  purpose. * *  Please cite the author in any work or product based on this material. * * =========================================================================== * * Author:  Denis Vakatov, Anton Lavrentiev * * File Description: *   Auxiliary API, mostly CONN-, URL-, and MIME-related *   (see in "ncbi_connutil.h" for more details). * */#include "ncbi_ansi_ext.h"#include "ncbi_priv.h"#include <connect/ncbi_connutil.h>#include <ctype.h>#include <errno.h>#include <stdlib.h>static const char* s_GetValue(const char* service, const char* param,                              char* value, size_t value_size,                              const char* def_value){    char        key[250];    char*       sec;    const char* val;    if (!param  ||  !value  ||  value_size <= 0)        return 0;    *value = '\0';    if (service  &&  *service) {        /* Service-specific inquiry */        if (strlen(service) + 1 + sizeof(DEF_CONN_REG_SECTION) +            strlen(param) + 1 > sizeof(key))            return 0;        /* First, environment search for 'service_CONN_param' */        sprintf(key, "%s_" DEF_CONN_REG_SECTION "_%s", service, param);        strupr(key);        if ((val = getenv(key)) != 0)            return strncpy0(value, val, value_size - 1);        /* Next, search for 'CONN_param' in '[service]' registry section */        sprintf(key, DEF_CONN_REG_SECTION "_%s", param);        sec = key + strlen(key) + 1;        strupr(key);        strcpy(sec, service);        strupr(sec);        CORE_REG_GET(sec, key, value, value_size, 0);        if (*value)            return value;    } else {        /* Common case. Form 'CONN_param' */        if (sizeof(DEF_CONN_REG_SECTION) + strlen(param) + 1 > sizeof(key))            return 0;        sprintf(key, DEF_CONN_REG_SECTION "_%s", param);        strupr(key);    }    /* Environment search for 'CONN_param' */    if ((val = getenv(key)) != 0)        return strncpy0(value, val, value_size - 1);    /* Last resort: Search for 'param' in default registry section */    strcpy(key, param);    strupr(key);    CORE_REG_GET(DEF_CONN_REG_SECTION, key, value, value_size, def_value);    return value;}/*********************************************************************** *  EXTERNAL ***********************************************************************/extern SConnNetInfo* ConnNetInfo_Create(const char* service){#define REG_VALUE(name, value, def_value) \    s_GetValue(service, name, value, sizeof(value), def_value)    SConnNetInfo* info = (SConnNetInfo*) malloc(sizeof(*info) +                                                (service  &&  *service                                                 ? strlen(service) + 1 : 0));    /* aux. storage for the string-to-int conversions, etc. */    char   str[32];    int    val;    double dbl;    char*  s;    if (!info)        return 0/*failure*/;    /* client host */    if (!SOCK_gethostbyaddr(0, info->client_host, sizeof(info->client_host)))        SOCK_gethostname(info->client_host, sizeof(info->client_host));    /* dispatcher host name */    REG_VALUE(REG_CONN_HOST, info->host, DEF_CONN_HOST);    /* dispatcher port number */    REG_VALUE(REG_CONN_PORT, str, 0);    val = atoi(str);    info->port = (unsigned short)(val > 0 ? val : DEF_CONN_PORT);    /* service path */    REG_VALUE(REG_CONN_PATH, info->path, DEF_CONN_PATH);    /* service args */    REG_VALUE(REG_CONN_ARGS, info->args, DEF_CONN_ARGS);    /* request method */    REG_VALUE(REG_CONN_REQ_METHOD, str, DEF_CONN_REQ_METHOD);    if (!*str  ||  strcasecmp(str, "ANY") == 0)        info->req_method = eReqMethod_Any;    else if (strcasecmp(str, "POST") == 0)        info->req_method = eReqMethod_Post;    else if (strcasecmp(str, "GET") == 0)        info->req_method = eReqMethod_Get;    /* connection timeout */    REG_VALUE(REG_CONN_TIMEOUT, str, 0);    if (strlen(str) > 2  &&  strncasecmp(str, "infinite", strlen(str)) == 0) {        info->timeout = 0;    } else {        info->timeout = &info->tmo;        dbl = atof(str);        if (dbl <= 0.0)            dbl = DEF_CONN_TIMEOUT;        info->timeout->sec  = (unsigned int) dbl;        info->timeout->usec = (unsigned int)            ((dbl - info->timeout->sec) * 1000000);    }    /* max. # of attempts to establish connection */    REG_VALUE(REG_CONN_MAX_TRY, str, 0);    val = atoi(str);    info->max_try = (unsigned short)(val > 0 ? val : DEF_CONN_MAX_TRY);    /* HTTP proxy server? */    REG_VALUE(REG_CONN_HTTP_PROXY_HOST, info->http_proxy_host,              DEF_CONN_HTTP_PROXY_HOST);    if (*info->http_proxy_host) {        /* yes, use the specified HTTP proxy server */        REG_VALUE(REG_CONN_HTTP_PROXY_PORT, str, 0);        val = atoi(str);        info->http_proxy_port = (unsigned short)            (val > 0 ? val : DEF_CONN_HTTP_PROXY_PORT);    } else        info->http_proxy_port = DEF_CONN_HTTP_PROXY_PORT;    /* non-transparent CERN-like firewall proxy server? */    REG_VALUE(REG_CONN_PROXY_HOST, info->proxy_host, DEF_CONN_PROXY_HOST);    /* turn on debug printout? */    REG_VALUE(REG_CONN_DEBUG_PRINTOUT, str, DEF_CONN_DEBUG_PRINTOUT);    if (*str  &&        (strcmp(str, "1") == 0  ||         strcasecmp(str, "true") == 0  ||         strcasecmp(str, "yes" ) == 0  ||         strcasecmp(str, "some") == 0)) {        info->debug_printout = eDebugPrintout_Some;    } else if (*str  &&               (strcasecmp(str, "data") == 0  ||                strcasecmp(str, "all" ) == 0)) {        info->debug_printout = eDebugPrintout_Data;    } else        info->debug_printout = eDebugPrintout_None;    /* stateless client? */    REG_VALUE(REG_CONN_STATELESS, str, DEF_CONN_STATELESS);    info->stateless = (*str  &&                       (strcmp(str, "1") == 0  ||                        strcasecmp(str, "true") == 0  ||                        strcasecmp(str, "yes" ) == 0));    /* firewall mode? */    REG_VALUE(REG_CONN_FIREWALL, str, DEF_CONN_FIREWALL);    info->firewall = (*str  &&                      (strcmp(str, "1") == 0  ||                       strcasecmp(str, "true") == 0  ||                       strcasecmp(str, "yes" ) == 0));    /* prohibit the use of local load balancer? */    REG_VALUE(REG_CONN_LB_DISABLE, str, DEF_CONN_LB_DISABLE);    info->lb_disable = (*str  &&                        (strcmp(str, "1") == 0  ||                         strcasecmp(str, "true") == 0  ||                         strcasecmp(str, "yes" ) == 0));    /* has no user header yet... */    info->http_user_header = 0;    /* not adjusted yet... */    info->http_proxy_adjusted = 0/*false*/;    /* store service name for which this structure has been created */    if (service  &&  *service) {        s = (char*) info + sizeof(*info);        strcpy(s, service);    } else        s = 0;    info->service = s;    /* done */    return info;#undef REG_VALUE}extern int/*bool*/ ConnNetInfo_AdjustForHttpProxy(SConnNetInfo* info){    if (info->http_proxy_adjusted  ||  !*info->http_proxy_host)        return 0/*false*/;    if (strlen(info->host) + strlen(info->path) + 16 > sizeof(info->path)) {        CORE_LOG(eLOG_Error,                 "[ConnNetInfo_AdjustForHttpProxy]  Adjusted path too long");        assert(0);        return 0/*false*/;    }    {{        char x_path[sizeof(info->path)];        sprintf(x_path, "http://%s:%hu%s%s", info->host, info->port,                *info->path == '/' ? "" : "/", info->path);        assert(strlen(x_path) < sizeof(x_path));        strcpy(info->path, x_path);    }}    assert(sizeof(info->host) >= sizeof(info->http_proxy_host));    strncpy0(info->host, info->http_proxy_host, sizeof(info->host) - 1);    info->port = info->http_proxy_port;    info->http_proxy_adjusted = 1/*true*/;    return 1/*true*/;}extern int/*bool*/ ConnNetInfo_ParseURL(SConnNetInfo* info, const char* url){    const char *s, *a;    char* p;    if (info->http_proxy_adjusted) {        /* undo proxy adjustment */        SConnNetInfo* temp = ConnNetInfo_Create(info->service);        if (!ConnNetInfo_ParseURL(temp, info->path)) {            ConnNetInfo_Destroy(temp);            return 0/*failure*/;        }        memcpy(info->host, temp->host, sizeof(info->host));        info->port = temp->port;        memcpy(info->path, temp->path, sizeof(info->path));        ConnNetInfo_Destroy(temp);        info->http_proxy_adjusted = 0/*false*/;    }    /* host & port first [both optional] */    if ((s = strstr(url, "://")) != 0) {        const char* h = s + 3; /* host starts here */        if (strncasecmp(url, "http://", 7) != 0)            return 0/*failure*/;        if (!(s = strchr(h, '/')))            s = h + strlen(h);        /* host ends at "a" */        if ((a = strchr(h, ':')) != 0 && a < s) {            unsigned short port;            int n;            if (sscanf(a, ":%hu%n", &port, &n) < 1 || a + n != s)                return 0/*failure*/;            info->port = port;        } else            a = s;        if ((size_t)(a - h) < sizeof(info->host)) {            memcpy(info->host, h, (size_t)(a - h));            info->host[(size_t)(a - h)] = '\0';        } else {            memcpy(info->host, h, sizeof(info->host) - 1);            info->host[sizeof(info->host) - 1] = '\0';        }    } else        s = url;    /* arguments */    if ((a = strchr(s, '?')) != 0)        strncpy0(info->args, a + 1, sizeof(info->args) - 1);    else        a = s + strlen(s);    /* path (NB: can be relative) */    if (s != url || *s == '/' || !(p = strrchr(info->path, '/'))) {        /* absolute path */        p = info->path;        if (!*s) {            s = "/";   /* in case of an empty path we take the root '/' */            a = s + 1;        }    } else        p++;    if ((size_t)(a - s) < sizeof(info->path) - (size_t)(p - info->path)) {        memcpy(p, s, (size_t)(a - s));        p[(size_t)(a - s)] = '\0';    } else {        memcpy(p, s, sizeof(info->path) - (size_t)(p - info->path) - 1);        info->path[sizeof(info->path) - 1] = '\0';    }    return 1/*success*/;}extern int/*bool*/ ConnNetInfo_SetUserHeader(SConnNetInfo* info,                                      const char*   user_header){    if (info->http_user_header)        free((void*) info->http_user_header);    if (user_header && *user_header) {        info->http_user_header = strdup(user_header);        return info->http_user_header ? 1/*success*/ : 0/*failure*/;    } else        info->http_user_header = 0;    return 1/*success*/;}extern int/*bool*/ ConnNetInfo_AppendUserHeader(SConnNetInfo* info,                                                const char*   user_header){    size_t oldlen, newlen;    char* new_header;    if (!info->http_user_header || !(oldlen = strlen(info->http_user_header)))        return ConnNetInfo_SetUserHeader(info, user_header);    if (!user_header || !(newlen = strlen(user_header)))        return 1/*success*/;    new_header = (char*)        realloc((void*) info->http_user_header, oldlen + newlen + 1);    if (!new_header)        return 0/*failure*/;    memcpy(&new_header[oldlen], user_header, newlen + 1);    info->http_user_header = new_header;    return 1/*success*/;}typedef enum {    eUserHeaderOp_Delete,    eUserHeaderOp_Extend,    eUserHeaderOp_Override} EUserHeaderOp;static int/*bool*/ s_ModifyUserHeader(SConnNetInfo* info,                                      const char*   user_header,                                      EUserHeaderOp op){    int/*bool*/ retval;    char*  new_header;    size_t newlinelen;    size_t newhdrlen;    char*  newline;    size_t hdrlen;    char*  hdr;    if (!user_header || !(newhdrlen = strlen(user_header)))        return 1/*success*/;    if (!(hdr = (char*) info->http_user_header) || !(hdrlen = strlen(hdr))) {        if (op == eUserHeaderOp_Delete)            return 1/*success*/;        if (!hdr && !(hdr = strdup("")))            return 0/*failure*/;        hdrlen = 0;    }    if (op != eUserHeaderOp_Delete) {        if (!(new_header = (char*) malloc(newhdrlen + 1)))            return 0/*failure*/;        memcpy(new_header, user_header, newhdrlen + 1);    } else        new_header = (char*) user_header; /* we actually won't modify it! */    retval = 1/*assume best: success*/;    for (newline = new_header; *newline; newline += newlinelen) {        char*  eol = strchr(newline, '\n');        char*  eot = strchr(newline,  ':');        int/*bool*/ used = 0;        size_t newtaglen;        char*  newtagval;        size_t linelen;        char*  line;        size_t len;        size_t l;        newlinelen = (size_t)            (eol ? eol - newline + 1 : new_header + newhdrlen - newline);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -