Example #1
0
static void handle_content_type(response_t *resp, const char *filepath) {
    char  *content_type = NULL, ext[20];
    int   dot_pos = -1;
    int   i;
    size_t  len = strlen(filepath);
    ENTRY   item, *ret;

    for (i = len - 1; i > 0; i--) {
        if (filepath[i] == '.') {
            dot_pos = i;
            break;
        }
    }

    if (dot_pos < 0) {
        // No '.' found in the file name (no extension part)
        return;
    }

    strncpy(ext, filepath + 1 + dot_pos, 20);
    strlowercase(ext, ext, 20);
    debug("File extension: %s", ext);
    
    item.key = ext;
    if (hsearch_r(item, FIND, &ret, &std_mime_type_hash) == 0) {
        return;
    }
    content_type = (char*) ret->data;
    if (content_type != NULL) {
        debug("Content type: %s", content_type);
        response_set_header(resp, "Content-Type", content_type); 
    }
}
Example #2
0
static int static_file_listdir(response_t *resp, const char *path,
                               const char *realpath) {
    struct dirent **ent_list, *ent;
    int    ent_len;
    char   buf[2048];
    int    pos = 0, i;

    debug("Opening dir: %s", realpath);
    if ((ent_len = scandir(realpath, &ent_list, dir_filter, versionsort)) < 0) {
        return static_file_handle_error(resp, -1);
    }
    resp->status = STATUS_OK;
    resp->connection = CONN_CLOSE;
    response_set_header(resp, "Content-Type", "text/html; charset=UTF-8");
    response_send_headers(resp, NULL);
    pos += snprintf(buf, 2048, listdir_header, path, path);
    for (i = 0; i < ent_len; i++) {
        ent = ent_list[i];
        pos += snprintf(buf + pos, 2048 - pos,
                        ent->d_type == DT_DIR ? listdir_dir : listdir_file,
                        ent->d_name, ent->d_name);
        if (2048 - pos < 255) {
            response_write(resp, buf, pos, NULL);
            pos = 0;
        }
        free(ent);
    }
    free(ent_list);
    pos += snprintf(buf + pos, 2048 - pos, listdir_footer, _BREEZE_NAME);
    response_write(resp, buf, pos, NULL);

    return HANDLER_DONE;
}
Example #3
0
static SLVAL
response_redirect(sl_vm_t* vm, SLVAL self, SLVAL url)
{
    response(vm)->status = 302;
    response_set_header(vm, self, sl_make_cstring(vm, "Location"), url);
    sl_exit(vm, sl_make_int(vm, 0));
    return self; /* never reached */
}
Example #4
0
static int handle_cache(request_t *req, response_t *resp,
                        const struct stat *st, const mod_static_conf_t *conf) {
    const char   *if_mod_since, *if_none_match;
    char   *etag;
    time_t  mtime, req_mtime;
    int    not_modified = 0;
    char   *buf;
    char   *cache_control;

    mtime = st->st_mtime;
    if_mod_since = request_get_header(req, "if-modified-since");
    if (if_mod_since != NULL &&
        parse_http_date(if_mod_since, &req_mtime) == 0 &&
        req_mtime == mtime) {
        debug("Resource not modified");
        not_modified = 1;
    }
    buf = response_alloc(resp, 32);
    format_http_date(&mtime, buf, 32);
    response_set_header(resp, "Last-Modified", buf);

    if (conf->enable_etag) {
        etag = generate_etag(st);
        if (not_modified) {
            if_none_match = request_get_header(req, "if-none-match");
            if (if_none_match == NULL ||
                strcmp(etag, if_none_match) != 0) {
                not_modified = 0;
            }
        }
        response_set_header(resp, "ETag", etag);
    }

    if (conf->expire_hours >= 0) {
        buf = response_alloc(resp, 32);
        mtime += conf->expire_hours * 3600;
        format_http_date(&mtime, buf, 32);
        response_set_header(resp, "Expires", buf);
        cache_control = response_alloc(resp, 20);
        snprintf(cache_control, 20, "max-age=%d", conf->expire_hours * 3600);
    } else {
        cache_control = "no-cache";
    }
    response_set_header(resp, "Cache-Control", cache_control);
    return not_modified;
}
Example #5
0
static SLVAL
response_set_cookie(sl_vm_t* vm, SLVAL self, SLVAL name, SLVAL value)
{
    SLVAL header;
    sl_expect(vm, name, vm->lib.String);
    sl_expect(vm, value, vm->lib.String);
    name = sl_string_url_encode(vm, name);
    value = sl_string_url_encode(vm, value);

    header = name;
    header = sl_string_concat(vm, header, sl_make_cstring(vm, "="));
    header = sl_string_concat(vm, header, value);

    return response_set_header(vm, self, sl_make_cstring(vm, "Set-Cookie"), header);
}
Example #6
0
int static_file_handle(request_t *req, response_t *resp,
                       handler_ctx_t *ctx) {
    mod_static_conf_t *conf;
    char              path[2048];
    int               fd = -1, res, use_301;
    struct stat       st;
    size_t            len, pathlen, filesize, fileoffset;
    ctx_state_t       val;

    conf = (mod_static_conf_t*) ctx->conf;
    len = strlen(conf->root);
    strncpy(path, conf->root, 2048);
    if (path[len - 1] == '/') {
        path[len - 1] = '\0';
    }
    if (req->path[0] != '/') {
        return response_send_status(resp, STATUS_BAD_REQUEST);
    }
    strncat(path, req->path, 2048 - len);
    debug("Request path: %s, real file path: %s", req->path, path);
    res = try_open_file(path, &fd, &st);
    if (res < 0) {
        return static_file_handle_error(resp, fd);
    } else if (res > 0) { // Is a directory, try index files.
        pathlen = strlen(path);
        use_301 = 0;
        if (path[pathlen - 1] != '/') {
            path[pathlen] = '/';
            path[pathlen + 1] = '\0';
            pathlen++;
            use_301 = 1;
        }
        //for (i = 0; i < 10 && res != 0 && conf->index[i] != NULL; i++) {
        //    path[pathlen] = '\0';
        //    strncat(path, conf->index[i], 2048 - pathlen);
        //    res = try_open_file(path, &fd, &st);
        //}
        path[pathlen] = '\0';
        strncat(path, conf->index, 2048 - pathlen);
        res = try_open_file(path, &fd, &st);
        path[pathlen] = '\0';
        if (res != 0) {
            if (conf->enable_list_dir) {
                if (use_301) {
                    // TODO Support HTTPS
                    snprintf(path, 2048, "http://%s%s/", req->host, req->path);
                    response_set_header(resp, "Location", path);
                    resp->status = STATUS_MOVED;
                    resp->content_length = 0;
                    response_send_headers(resp, NULL);
                    return HANDLER_DONE;
                }
                show_hidden_file = conf->show_hidden_file;
                return static_file_listdir(resp, req->path, path);
            } else {
                return static_file_handle_error(resp, fd);
            }
        }
    }

    fileoffset = 0;
    filesize = st.st_size;
    res = handle_range(req, resp, &fileoffset, &filesize);
    if (res < 0) {
        resp->status = STATUS_OK;
    } else if (res == 0) {
        resp->status = STATUS_PARTIAL_CONTENT;
    } else {
        return response_send_status(resp, STATUS_RANGE_NOT_SATISFIABLE);
    }

    resp->content_length = filesize;
    handle_content_type(resp, path);
    if (handle_cache(req, resp, &st, conf)) {
        return response_send_status(resp, STATUS_NOT_MODIFIED);
    }
    
    val.as_int = fd;
    context_push(ctx, val);
    val.as_long = fileoffset;
    context_push(ctx, val);
    val.as_long = filesize;
    context_push(ctx, val);
    debug("sending headers");
    response_send_headers(resp, static_file_write_content);
    return HANDLER_UNFISHED;
}