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

📄 get.c

📁 boa:Linux系统中的轻量级Web服务
💻 C
📖 第 1 页 / 共 2 页
字号:
         * the client knows there has been a problem.         * We run the risk of accidentally sending the right number         * of bytes (or a few too many) and the client         * won't be the wiser.         */        req->status = DEAD;        fprintf(stderr, "%sGot SIGBUS in write(2)!\n", get_commonlog_time());        return 0;    }    if (bytes_written < 0) {        if (errno == EWOULDBLOCK || errno == EAGAIN)            return -1;        /* request blocked at the pipe level, but keep going */        else {            if (errno != EPIPE) {                log_error_doc(req);                /* Can generate lots of log entries, */                perror("write");                /* OK to disable if your logs get too big */            }            req->status = DEAD;            return 0;        }    }    req->filepos += bytes_written;    if (req->filepos == req->filesize) { /* EOF */        return 0;    } else        return 1;               /* more to do */}/* * Name: get_dir * Description: Called from process_get if the request is a directory. * statbuf must describe directory on input, since we may need its *   device, inode, and mtime. * statbuf is updated, since we may need to check mtimes of a cache. * returns: *  -1 error *  0  cgi (either gunzip or auto-generated) *  >0  file descriptor of file */int get_dir(request * req, struct stat *statbuf){    char pathname_with_index[MAX_PATH_LENGTH];    int data_fd;    if (directory_index) {      /* look for index.html first?? */        strcpy(pathname_with_index, req->pathname);        strcat(pathname_with_index, directory_index);        /*           sprintf(pathname_with_index, "%s%s", req->pathname, directory_index);         */        data_fd = open(pathname_with_index, O_RDONLY);        if (data_fd != -1) {    /* user's index file */            strcpy(req->request_uri, directory_index); /* for mimetype */            fstat(data_fd, statbuf);            return data_fd;        }        if (errno == EACCES) {            send_r_forbidden(req);            return -1;        } else if (errno != ENOENT) {            /* if there is an error *other* than EACCES or ENOENT */            send_r_not_found(req);            return -1;        }#ifdef GUNZIP        /* if we are here, trying index.html didn't work         * try index.html.gz         */        strcat(pathname_with_index, ".gz");        data_fd = open(pathname_with_index, O_RDONLY);        if (data_fd != -1) {    /* user's index file */            close(data_fd);            req->response_status = R_REQUEST_OK;            SQUASH_KA(req);            if (req->pathname)                free(req->pathname);            req->pathname = strdup(pathname_with_index);            if (!req->pathname) {                log_error_time();                perror("strdup");                send_r_error(req);                return 0;            }            if (!req->simple) {                req_write(req, "HTTP/1.0 200 OK-GUNZIP\r\n");                print_http_headers(req);                print_last_modified(req);                req_write(req, "Content-Type: ");                req_write(req, get_mime_type(directory_index));                req_write(req, "\r\n\r\n");                req_flush(req);            }            if (req->method == M_HEAD)                return 0;            return init_cgi(req);        }#endif    }    /* only here if index.html, index.html.gz don't exist */    if (dirmaker != NULL) {     /* don't look for index.html... maybe automake? */        req->response_status = R_REQUEST_OK;        SQUASH_KA(req);        /* the indexer should take care of all headers */        if (!req->simple) {            req_write(req, "HTTP/1.0 200 OK\r\n");            print_http_headers(req);            print_last_modified(req);            req_write(req, "Content-Type: text/html\r\n\r\n");            req_flush(req);        }        if (req->method == M_HEAD)            return 0;        return init_cgi(req);        /* in this case, 0 means success */    } else if (cachedir) {        return get_cachedir_file(req, statbuf);    } else {                    /* neither index.html nor autogenerate are allowed */        send_r_forbidden(req);        return -1;              /* nothing worked */    }}int get_cachedir_file(request * req, struct stat *statbuf){    char pathname_with_index[MAX_PATH_LENGTH];    int data_fd;    time_t real_dir_mtime;    real_dir_mtime = statbuf->st_mtime;    sprintf(pathname_with_index, "%s/dir.%d.%ld",            cachedir, (int) statbuf->st_dev, statbuf->st_ino);    data_fd = open(pathname_with_index, O_RDONLY);    if (data_fd != -1) {        /* index cache */        fstat(data_fd, statbuf);        if (statbuf->st_mtime > real_dir_mtime) {            statbuf->st_mtime = real_dir_mtime; /* lie */            strcpy(req->request_uri, directory_index); /* for mimetype */            return data_fd;        }        close(data_fd);        unlink(pathname_with_index); /* cache is stale, delete it */    }    if (index_directory(req, pathname_with_index) == -1)        return -1;    data_fd = open(pathname_with_index, O_RDONLY); /* Last chance */    if (data_fd != -1) {        strcpy(req->request_uri, directory_index); /* for mimetype */        fstat(data_fd, statbuf);        statbuf->st_mtime = real_dir_mtime; /* lie */        return data_fd;    }    boa_perror(req, "re-opening dircache");    return -1;                  /* Nothing worked. */}/* * Name: index_directory * Description: Called from get_cachedir_file if a directory html * has to be generated on the fly * returns -1 for problem, else 0 * This version is the fastest, ugliest, and most accurate yet. * It solves the "stale size or type" problem by not ever giving * the size or type.  This also speeds it up since no per-file * stat() is required. */int index_directory(request * req, char *dest_filename){    DIR *request_dir;    FILE *fdstream;    struct dirent *dirbuf;    int bytes = 0;    char *escname = NULL;    if (chdir(req->pathname) == -1) {        if (errno == EACCES || errno == EPERM) {            send_r_forbidden(req);        } else {            log_error_doc(req);            perror("chdir");            send_r_bad_request(req);        }        return -1;    }    request_dir = opendir(".");    if (request_dir == NULL) {        int errno_save = errno;        send_r_error(req);        log_error_time();        fprintf(stderr, "directory \"%s\": ", req->pathname);        errno = errno_save;        perror("opendir");        return -1;    }    fdstream = fopen(dest_filename, "w");    if (fdstream == NULL) {        boa_perror(req, "dircache fopen");        closedir(request_dir);        return -1;    }    bytes += fprintf(fdstream,                     "<HTML><HEAD>\n<TITLE>Index of %s</TITLE>\n</HEAD>\n\n",                     req->request_uri);    bytes += fprintf(fdstream, "<BODY>\n\n<H2>Index of %s</H2>\n\n<PRE>\n",                     req->request_uri);    while ((dirbuf = readdir(request_dir))) {        if (!strcmp(dirbuf->d_name, "."))            continue;        if (!strcmp(dirbuf->d_name, "..")) {            bytes += fprintf(fdstream,                             " [DIR] <A HREF=\"../\">Parent Directory</A>\n");            continue;        }        if ((escname = escape_string(dirbuf->d_name, NULL)) != NULL) {            bytes += fprintf(fdstream, " <A HREF=\"%s\">%s</A>\n",                             escname, dirbuf->d_name);            free(escname);            escname = NULL;        }    }    closedir(request_dir);    bytes += fprintf(fdstream, "</PRE>\n\n</BODY>\n</HTML>\n");    fclose(fdstream);    chdir(server_root);    req->filesize = bytes;      /* for logging transfer size */    return 0;                   /* success */}

⌨️ 快捷键说明

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