zoukankan      html  css  js  c++  java
  • C 语言 断点续传2

    /* packet handler */
    int xhttpd_packet_handler(CONN *conn, CB_DATA *packet)
    {
        char buf[HTTP_BUF_SIZE], file[HTTP_PATH_MAX], line[HTTP_PATH_MAX], *host = NULL,
             *mime = NULL, *home = NULL, *pp = NULL, *p = NULL, *end = NULL, *root = NULL,
             *s = NULL, *outfile = NULL, *name = NULL, *encoding = NULL;
        int i = 0, n = 0, found = 0, nmime = 0, mimeid = 0, is_need_compress = 0, keepalive = 0;
        off_t from = 0, to = 0, len = 0;
        struct stat st = {0};
        HTTP_REQ http_req = {0};
        void *dp = NULL;

        if(conn && packet)
        {
            p = packet->data;
            end = packet->data + packet->ndata;
            //fprintf(stdout, "%s", p);
            if(http_request_parse(p, end, &http_req, http_headers_map) == -1)
            {
                //fprintf(stdout, "%s::%d REQUEST:%s path:%s\n", __FILE__, __LINE__, packet->data, http_req.path);
                goto err;
            }
            if(http_req.reqid == HTTP_GET)
            {
                REALLOG(logger, "[%s:%d] GET %s", conn->remote_ip, conn->remote_port, http_req.path);
                //get vhost
                if((n = http_req.headers[HEAD_REQ_HOST]) > 0)
                {
                    p = http_req.hlines + n;
                    if(strncasecmp(p, "www.", 4) == 0) p += 4;
                    host = p;
                    while(*p != ':' && *p != '\0')++p;
                    *p = '\0';
                    n = p - host;
                    TRIETAB_GET(namemap, host, n, dp);
                    if((i = ((long)dp - 1)) >= 0) home = httpd_vhosts[i].home;
                }
                if(home == NULL) home = httpd_home;
                if(home == NULL) goto err;
                p = file;
                p += sprintf(p, "%s", home);
                root = p;
                if(http_req.path[0] != '/')
                    p += sprintf(p, "/%s", http_req.path);
                else
                    p += sprintf(p, "%s", http_req.path);
                //fprintf(stdout, "outfile:%s\r\n", file);
                if((n = (p - file)) > 0 && lstat(file, &st) == 0)
                {
                    if(S_ISDIR(st.st_mode))
                    {
                        i = 0;
                        found = 0;
                        if(p > file && *(p-1) != '/') *p++ = '/';
                        while(i < nindexes && http_indexes[i])
                        {
                            pp = p;
                            pp += sprintf(pp, "%s", http_indexes[i]);
                            if(access(file, F_OK) == 0 && lstat(file, &st) == 0)
                            {
                                found = 1;
                                p = pp;
                                break;
                            }
                            ++i;
                        }
                        //index view
                        if(found == 0 && http_indexes_view && (*p = '\0') >= 0)
                        {
                            end = --p;
                            if(xhttpd_index_view(conn, &http_req, file, root, end) == 0) return 0;
                            else goto err;
                        }
                    }
                    s = mime = line + HTTP_PATH_MAX - 1;
                    *s = '\0';
                    pp = --p ;
                    while(pp > file && *pp != '.')
                    {
                        if(*pp >= 'A' && *pp <= 'Z')
                        {
                            *--mime = *pp + ('a' - 'A');
                        }
                        else *--mime = *pp;
                        --pp;
                    }
                    //while( > file && *mime != '.')--mime;
                    if(mime > line) nmime = s - mime;
                    //no content
                    if(st.st_size == 0)
                    {
                        return conn->push_chunk(conn, HTTP_NO_CONTENT,
                                strlen(HTTP_NO_CONTENT));
                    }
                    //if not change
                    else if((n = http_req.headers[HEAD_REQ_IF_MODIFIED_SINCE]) > 0
                            && str2time(http_req.hlines + n) == st.st_mtime)
                    {
                        return conn->push_chunk(conn, HTTP_NOT_MODIFIED,
                                strlen(HTTP_NOT_MODIFIED));
                    }
                    else
                    {
                        //range
                        if((n = http_req.headers[HEAD_REQ_RANGE]) > 0)
                        {
                            p = http_req.hlines + n;
                            while(*p == 0x20 || *p == '\t')++p;
                            if(strncasecmp(p, "bytes=", 6) == 0) p += 6;
                            while(*p == 0x20)++p;
                            if(*p == '-')
                            {
                                ++p;
                                while(*p == 0x20)++p;
                                if(*p >= '0' && *p <= '9') to = (off_t)atoll(p) + 1;
                            }
                            else if(*p >= '0' && *p <= '9')
                            {
                                from = (off_t) atoll(p++);
                                while(*p != '-')++p;
                                ++p;
                                while(*p == 0x20)++p;
                                if(*p >= '0' && *p <= '9') to = (off_t)atoll(p) + 1;
                            }
                        }
                        if(to == 0) to = st.st_size;
                        len = to - from;
                        //fprintf(stdout, "%s::%d mime:%s[%d] len:%lld [%lld-%lld]\n", __FILE__, __LINE__, mime, nmime, LL(len), LL(from), LL(to));
                        //mime
                        if(mime && nmime > 0)
                        {
                            TRIETAB_GET(namemap, mime, nmime, dp);
                            if((mimeid = ((long)dp - 1)) >= 0
                                    && (n = http_req.headers[HEAD_REQ_ACCEPT_ENCODING]) > 0
                                    && strstr(http_mime_types[mimeid].s, "text"))
                            {
                                p = http_req.hlines + n;
    #ifdef HAVE_ZLIB
                                if(strstr(p, "deflate"))
                                    is_need_compress |= HTTP_ENCODING_DEFLATE;
                                if(strstr(p, "gzip"))
                                    is_need_compress |= HTTP_ENCODING_GZIP;
                                //if(strstr(p, "compress")) is_need_compress |= HTTP_ENCODING_COMPRESS;
    #endif
    #ifdef HAVE_BZ2LIB
                                if(strstr(p, "bzip2"))
                                    is_need_compress |= HTTP_ENCODING_BZIP2;
    #endif
                            }
                            if(mimeid < 0)
                            {
                                end = root + 1;
                                while(*end != '\0')
                                {
                                    if(*end == '/') name = ++end;
                                    else ++end;
                                }
                            }
                        }
                        if(is_need_compress > 0 && xhttpd_compress_handler(conn,
                                    &http_req, host, is_need_compress, mimeid, file,
                                    root, from, to, &st) == 0)
                        {
                            return 0;
                        }
                        else outfile = file;
                        p = buf;
                        if(from > 0)
                            p += sprintf(p, "HTTP/1.1 206 Partial Content\r\nAccept-Ranges: bytes\r\n"
                                    "Content-Range: bytes %lld-%lld/%lld\r\n",
                                    LL(from), LL(to - 1), LL(st.st_size));
                        else
                            p += sprintf(p, "HTTP/1.1 200 OK\r\nAccept-Ranges: bytes\r\n");
                        p += sprintf(p, "Content-Type: %s; charset=%s\r\n",
                                http_mime_types[mimeid].s, http_default_charset);
                        //fprintf(stdout, "%s::%d outfile:%s\n", __FILE__, __LINE__, outfile);
                        if((n = http_req.headers[HEAD_GEN_CONNECTION]) > 0)
                        {
                            p += sprintf(p, "Connection: %s\r\n", http_req.hlines + n);
                            if((strncasecmp(http_req.hlines + n, "close", 5)) !=0 )
                                keepalive = 1;
                        }
                        else
                        {
                            p += sprintf(p, "Connection: close\r\n");
                        }
                        p += sprintf(p, "Last-Modified:");
                        p += GMTstrdate(st.st_mtime, p);
                        p += sprintf(p, "%s", "\r\n");//date end
                        if(encoding) p += sprintf(p, "Content-Encoding: %s\r\n", encoding);
                        if(name)
                            p += sprintf(p, "Content-Disposition: attachment, filename='%s'\r\n", name);
                        p += sprintf(p, "Date: ");p += GMTstrdate(time(NULL),p);p += sprintf(p,"\r\n");
                        p += sprintf(p, "Content-Length: %lld\r\n", LL(len));
                        p += sprintf(p, "Server: xhttpd/%s\r\n\r\n", XHTTPD_VERSION);
                        conn->push_chunk(conn, buf, (p - buf));
                        conn->push_file(conn, outfile, from, len);
                        if(!keepalive) conn->over(conn);
                        return 0;
                    }
                }
            }
            else if(http_req.reqid == HTTP_POST)
            {
                REALLOG(logger, "[%s:%d] POST %s", conn->remote_ip, conn->remote_port, http_req.path);
                if((n = http_req.headers[HEAD_ENT_CONTENT_LENGTH]) > 0
                        && (p = (http_req.hlines + n)) && (n = atoi(p)) > 0)
                {
                    conn->save_cache(conn, &http_req, sizeof(HTTP_REQ));
                    return conn->recv_chunk(conn, n);
                }
                return conn->push_chunk(conn, HTTP_NOT_FOUND, strlen(HTTP_NOT_FOUND));
            }
    err:
            return conn->push_chunk(conn, HTTP_NOT_FOUND, strlen(HTTP_NOT_FOUND));
        }
        return -1;
    }

    /* data handler */
    int xhttpd_data_handler(CONN *conn, CB_DATA *packet, CB_DATA *cache, CB_DATA *chunk)
    {
        if(conn)
        {
            return conn->push_chunk(conn, HTTP_NO_CONTENT, strlen(HTTP_NO_CONTENT));
        }
        return -1;
    }

    /* OOB handler */
    int xhttpd_oob_handler(CONN *conn, CB_DATA *oob)
    {
        if(conn && conn->push_chunk)
        {
            conn->push_chunk((CONN *)conn, ((CB_DATA *)oob)->data, oob->ndata);
            return oob->ndata;
        }
        return -1;
    }

    /* signal */
    static void xhttpd_stop(int sig)
    {
        switch (sig)
        {
            case SIGINT:
            case SIGTERM:
                fprintf(stderr, "xhttpd server is interrupted by user.\n");
                if(sbase)sbase->stop(sbase);
                break;
            default:
                break;
        }
    }

  • 相关阅读:
    组合模式
    MySQL8.0 下载安装启动(Windows10)
    OI如逆旅,我亦是行人——省选
    闲话—江湖痴情浅,信步余生。平剑红烛,青丝微绾,却话奁中。
    此时彼方
    CSP 2019游记 & 退役记
    西狂 杨过
    SDOI 2019 Round1 游记
    NOIP2018游记
    未来可期,不知所终
  • 原文地址:https://www.cnblogs.com/zzxap/p/2175779.html
Copyright © 2011-2022 走看看