Example #1
0
int
make_request(evbase_t         * evbase,
             evthr_t          * evthr,
             const char * const host,
             const short        port,
             const char * const path,
             evhtp_headers_t  * headers,
             evhtp_callback_cb  cb,
             void             * arg) {
    evhtp_connection_t * conn;
    evhtp_request_t    * request;

    conn         = evhtp_connection_new(evbase, host, port);
    conn->thread = evthr;
    request      = evhtp_request_new(cb, arg);

    evhtp_headers_add_header(request->headers_out,
                             evhtp_header_new("Host", "localhost", 0, 0));
    evhtp_headers_add_header(request->headers_out,
                             evhtp_header_new("User-Agent", "libevhtp", 0, 0));
    evhtp_headers_add_header(request->headers_out,
                             evhtp_header_new("Connection", "close", 0, 0));

    evhtp_headers_add_headers(request->headers_out, headers);

    printf("Making backend request...\n");
    evhtp_make_request(conn, request, htp_method_GET, path);
    printf("Ok.\n");

    return 0;
}
Example #2
0
/**
 * @brief echo_cb Callback function of echo test.
 *
 * @param req The request of a test url.
 * @param arg It is not useful.
 */
void echo_cb(evhtp_request_t *req, void *arg)
{
    evbuffer_add_printf(req->buffer_out, "<html><body><h1>zimg works!</h1></body></html>");
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1));
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
    evhtp_send_reply(req, EVHTP_RES_OK);
}
Example #3
0
static void
redirect_to_upload_error (evhtp_request_t *req,
                          const char *repo_id,
                          const char *parent_dir,
                          const char *filename,
                          int error_code)
{
    char *seahub_url, *escaped_path, *escaped_fn = NULL;
    char url[1024];

    seahub_url = seaf->session->base.service_url;
    escaped_path = g_uri_escape_string (parent_dir, NULL, FALSE);
    if (filename) {
        escaped_fn = g_uri_escape_string (filename, NULL, FALSE);
        snprintf(url, 1024, "%s/repo/upload_error/%s?p=%s&fn=%s&err=%d",
                 seahub_url, repo_id, escaped_path, escaped_fn, error_code);
    } else {
        snprintf(url, 1024, "%s/repo/upload_error/%s?p=%s&err=%d",
                 seahub_url, repo_id, escaped_path, error_code);
    }
    g_free (escaped_path);
    g_free (escaped_fn);

    evhtp_headers_add_header(req->headers_out,
                             evhtp_header_new("Location",
                                              url, 1, 1));
    evhtp_headers_add_header(req->headers_out,
                             evhtp_header_new("Content-Length",
                                              "0", 1, 1));
    evhtp_send_reply(req, EVHTP_RES_SEEOTHER);
}
Example #4
0
/**
 * @brief dump_request_cb The callback of a dump request.
 *
 * @param req The request you want to dump.
 * @param arg It is not useful.
 */
void dump_request_cb(evhtp_request_t *req, void *arg)
{
    const char *uri = req->uri->path->full;

	//switch (evhtp_request_t_get_command(req)) {
    int req_method = evhtp_request_get_method(req);
    if(req_method >= 16)
        req_method = 16;

	LOG_PRINT(LOG_DEBUG, "Received a %s request for %s", method_strmap[req_method], uri);
    evbuffer_add_printf(req->buffer_out, "uri : %s\r\n", uri);
    evbuffer_add_printf(req->buffer_out, "query : %s\r\n", req->uri->query_raw);
    evhtp_headers_for_each(req->uri->query, print_headers, req->buffer_out);
    evbuffer_add_printf(req->buffer_out, "Method : %s\n", method_strmap[req_method]);
    evhtp_headers_for_each(req->headers_in, print_headers, req->buffer_out);

	evbuf_t *buf = req->buffer_in;;
	puts("Input data: <<<");
	while (evbuffer_get_length(buf)) {
		int n;
		char cbuf[128];
		n = evbuffer_remove(buf, cbuf, sizeof(buf)-1);
		if (n > 0)
			(void) fwrite(cbuf, 1, n, stdout);
	}
	puts(">>>");

    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1));
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/plain", 0, 0));
    evhtp_send_reply(req, EVHTP_RES_OK);
}
Example #5
0
int
main(int argc, char ** argv) {
    evbase_t           * evbase;
    evhtp_connection_t * conn;
    evhtp_request_t    * request;

    evbase  = event_base_new();
    conn    = evhtp_connection_new(evbase, "75.126.169.52", 80);
    request = evhtp_request_new(request_cb, evbase);

    evhtp_set_hook(&request->hooks, evhtp_hook_on_read, print_data, evbase);
    evhtp_set_hook(&request->hooks, evhtp_hook_on_new_chunk, print_new_chunk_len, NULL);
    evhtp_set_hook(&request->hooks, evhtp_hook_on_chunk_complete, print_chunk_complete, NULL);
    evhtp_set_hook(&request->hooks, evhtp_hook_on_chunks_complete, print_chunks_complete, NULL);

    evhtp_headers_add_header(request->headers_out,
                             evhtp_header_new("Host", "ieatfood.net", 0, 0));
    evhtp_headers_add_header(request->headers_out,
                             evhtp_header_new("User-Agent", "libevhtp", 0, 0));
    evhtp_headers_add_header(request->headers_out,
                             evhtp_header_new("Connection", "close", 0, 0));

    evhtp_make_request(conn, request, htp_method_GET, "/");

    event_base_loop(evbase, 0);
    event_base_free(evbase);

    return 0;
}
Example #6
0
/**
 * Serves a PNG file of the hash.
 */
void route_image(evhtp_request_t *req, void *arg) {
    // redisReply *reply;

    evhtp_uri_t *uri = req->uri;

    int side = 128;
    char *hash = "";

    char *res = uri->path->full;
    int ind = 0;
    res = strtok((char *) res, "/");
    while (res != NULL) {
        if (ind == 0) {
            if (strlen(res) == 32) {
                hash = res;
            } else if (strcmp(res, "avatar") == 0) {
                ind--;
            } else {
                route_400(req);
                return;
            }
        }
        if (ind == 1) {
            side = atoi(res);
            if (side == 0) {
                side = defsize;
            } else if (side < minsize) {
                side = minsize;
            } else if (side > maxsize) {
                side = maxsize;
            }
        }
        res = strtok(NULL, "/");
        ind++;
    }

    char *etag = malloc(sizeof(char) * 1024);
    sprintf(etag, "\"%s-%d\"", hash, side);
    
    evhtp_kv_t *etagin = evhtp_headers_find_header(req->headers_in, "If-None-Match");
    if(etagin && strcmp(etag, etagin->val) == 0) {
        free(etag);
        evhtp_send_reply(req, 304);
        return;
    }

    make_image(hash, req->buffer_out, side);
    evhtp_headers_add_header(req->headers_out,
            evhtp_header_new("Content-Type", "image/png", 0, 0));
    evhtp_headers_add_header(req->headers_out,
            evhtp_header_new("Cache-Control", "public", 0, 0));
    evhtp_headers_add_header(req->headers_out,
            evhtp_header_new("ETag", etag, 0, 1));
    free(etag);
    evhtp_send_reply(req, 200);
}
Example #7
0
/**
 * @brief zimg_attachment_set set zimg response Content-Disposition
 *
 * @param request the request of evhtp
 *
 * @return 1 for set true
 */
int zimg_attachment_set(evhtp_request_t *request, char* filename)
{
    LOG_PRINT(LOG_DEBUG, "origin url: %s", filename);
    char att[256];
    if ( strlen(filename)>0 )
    {
        zimg_url_decode(filename,strlen(filename));
        LOG_PRINT(LOG_DEBUG, "decoded url: %s", filename);
    }
    snprintf(att,sizeof(att)-1,"attachment;filename=\"%s\"",filename);
    evhtp_headers_add_header(request->headers_out, evhtp_header_new("Content-Disposition", att, 0, 1));
    evhtp_headers_add_header(request->headers_out, evhtp_header_new("Content-Type", "application/octet-stream", 0, 0));
    return 1;
}
Example #8
0
/**
 * Index route, serves a static file and handles a redirect.
 */
void route_index(evhtp_request_t *req, void *arg) {
    evhtp_uri_t *uri = req->uri;
    evhtp_query_t *query = uri->query;
    const char *parq = evhtp_kv_find(query, "q");
    const char *pars = evhtp_kv_find(query, "s");
    const char *parm = evhtp_kv_find(query, "m");
    if (parq) {
        char *m = malloc(sizeof (char)*64);
        char *tmp = makelower(parq, strlen(parq));
        char *md = md5((const char *) tmp, strlen(parq));
        free(tmp);
        if (parm) {
            sprintf(m, "/meta/%s", md);
        } else if (pars) {
            sprintf(m, "/%s/%d", md, atoi(pars));
        } else {
            sprintf(m, "/%s", md);
        }
        free(md);
        evhtp_headers_add_header(req->headers_out,
                evhtp_header_new("Location", m, 0, 1));
        free(m);
        evhtp_send_reply(req, 301);
    } else {
        serve_static(req, "static/index.html", "text/html");
    }
}
Example #9
0
int json_return(evhtp_request_t *req, int err_no, const char *md5sum, int post_size)
{
    //json sample:
    //{"ret":true,"info":{"size":"1024", "md5":"edac35fd4b0059d3218f0630bc56a6f4"}}
    //{"ret":false,"error":{"code":"1","message":"\u9a8c\u8bc1\u5931\u8d25"}}
    cJSON *j_ret = cJSON_CreateObject();
    cJSON *j_ret_info = cJSON_CreateObject();
    if(err_no == -1)
    {
        cJSON_AddBoolToObject(j_ret, "ret", 1);
        cJSON_AddStringToObject(j_ret_info, "md5", md5sum);
        cJSON_AddNumberToObject(j_ret_info, "size", post_size);
        cJSON_AddItemToObject(j_ret, "info", j_ret_info);
    }
    else
    {
        cJSON_AddBoolToObject(j_ret, "ret", 0);
        cJSON_AddNumberToObject(j_ret_info, "code", err_no);
        LOG_PRINT(LOG_DEBUG, "post_error_list[%d]: %s", err_no, post_error_list[err_no]);
        cJSON_AddStringToObject(j_ret_info, "message", post_error_list[err_no]);
        cJSON_AddItemToObject(j_ret, "error", j_ret_info);
    }
    char *ret_str_unformat = cJSON_PrintUnformatted(j_ret);
    LOG_PRINT(LOG_DEBUG, "ret_str_unformat: %s", ret_str_unformat);
    evbuffer_add_printf(req->buffer_out, "%s", ret_str_unformat);
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "application/json", 0, 0));
    cJSON_Delete(j_ret);
    free(ret_str_unformat);
    return 0;
}
Example #10
0
/**
 * @brief admin_img the function to deal with admin reqeust for disk mode
 *
 * @param req the evhtp request
 * @param md5 the file md5
 * @param t admin type
 *
 * @return 1 for OK, 2 for 404 not found and -1 for fail
 */
int admin_img(evhtp_request_t *req, thr_arg_t *thr_arg, char *md5, int t)
{
    int result = -1;

    LOG_PRINT(LOG_DEBUG, "amdin_img() start processing admin request...");
    char whole_path[512];
    int lvl1 = str_hash(md5);
    int lvl2 = str_hash(md5 + 3);
    snprintf(whole_path, 512, "%s/%d/%d/%s", settings.img_path, lvl1, lvl2, md5);
    LOG_PRINT(LOG_DEBUG, "whole_path: %s", whole_path);

    if(is_dir(whole_path) == -1)
    {
        LOG_PRINT(LOG_DEBUG, "path: %s is not exist!", whole_path);
        return 2;
    }

    if(t == 1)
    {
        if(delete_file(whole_path) != -1)
        {
            result = 1;
            evbuffer_add_printf(req->buffer_out, 
                "<html><body><h1>Admin Command Successful!</h1> \
                <p>MD5: %s</p> \
                <p>Command Type: %d</p> \
                </body></html>",
                md5, t);
            evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
        }
    }
Example #11
0
/* It's a bug of libevhtp that it doesn't set Content-Length automatically
 * in response to a multipart request.
 * Just add it in our code.
 */
static void
set_content_length_header (evhtp_request_t *req)
{
    char lstr[128];

    snprintf(lstr, sizeof(lstr), "%zu", evbuffer_get_length(req->buffer_out));

    evhtp_headers_add_header(req->headers_out,
                             evhtp_header_new("Content-Length", lstr, 1, 1));
}
Example #12
0
/**
 * @brief zimg_etag_set set zimg response etag
 *
 * @param request the request of evhtp
 * @param buff response body buffer
 * @param len body buffer len
 *
 * @return 1 for set true and 2 for 304
 */
int zimg_etag_set(evhtp_request_t *request, char *buff, size_t len)
{
    int result = 1;
    LOG_PRINT(LOG_DEBUG, "Begin to Caculate MD5...");
    md5_state_t mdctx;
    md5_byte_t md_value[16];
    char md5sum[33];
    int i;
    int h, l;
    md5_init(&mdctx);
    md5_append(&mdctx, (const unsigned char*)(buff), len);
    md5_finish(&mdctx, md_value);

    for(i=0; i<16; ++i)
    {
        h = md_value[i] & 0xf0;
        h >>= 4;
        l = md_value[i] & 0x0f;
        md5sum[i * 2] = (char)((h >= 0x0 && h <= 0x9) ? (h + 0x30) : (h + 0x57));
        md5sum[i * 2 + 1] = (char)((l >= 0x0 && l <= 0x9) ? (l + 0x30) : (l + 0x57));
    }
    md5sum[32] = '\0';
    LOG_PRINT(LOG_DEBUG, "md5: %s", md5sum);

    const char *etag_var = evhtp_header_find(request->headers_in, "If-None-Match");
    LOG_PRINT(LOG_DEBUG, "If-None-Match: %s", etag_var);
    if(etag_var == NULL)
    {
        evhtp_headers_add_header(request->headers_out, evhtp_header_new("Etag", md5sum, 0, 1));
    }
    else
    {
        if(strncmp(md5sum, etag_var, 32) == 0)
        {
            result = 2;
        }
        else
        {
            evhtp_headers_add_header(request->headers_out, evhtp_header_new("Etag", md5sum, 0, 1));
        }
    }
    return result;
}
Example #13
0
void
zxy_add_http_header(
        zxy_request_context *context,
        const std::string& key,
        const std::string& val)
{
    const evhtp_request_t *request = context->request;
    evhtp_headers_add_header(
            request->headers_out,
            evhtp_header_new(key.c_str(), val.c_str(), 1, 1));
}
Example #14
0
 void add_header_to_incoming_req(const std::string& name, 
                                 const std::string& value)
 {
   // This takes the name and value for the new header. These
   // are copied to avoid memory scribblers (controlled by the 1, 1
   // parameters)
   evhtp_header_t* new_header = evhtp_header_new(name.c_str(),
                                                 value.c_str(),
                                                 1, 1);
   evhtp_headers_add_header(_req->headers_in, new_header);
 }
Example #15
0
/**
 * @brief zimg_headers_add add header to evhtp request from conf
 *
 * @param req the evhtp request
 * @param hcf zimg_header_conf
 *
 * @return 1 for OK and -1 for fail
 */
static int zimg_headers_add(evhtp_request_t *req, zimg_headers_conf_t *hcf)
{
    if(hcf == NULL) return -1;
    zimg_headers_t *headers = hcf->headers;
    LOG_PRINT(LOG_DEBUG, "headers: %d", hcf->n);

    while(headers)
    {
        evhtp_headers_add_header(req->headers_out, evhtp_header_new(headers->value->key, headers->value->value, 1, 1));
        headers = headers->next;
    }
    return 1;
}
Example #16
0
static void
redirect_to_success_page (evhtp_request_t *req,
                          const char *repo_id,
                          const char *parent_dir)
{
    char *seahub_url, *escaped_path;
    char url[1024];

    seahub_url = seaf->session->base.service_url;
    escaped_path = g_uri_escape_string (parent_dir, NULL, FALSE);
    snprintf(url, 1024, "%s/repo/%s?p=%s", seahub_url, repo_id, escaped_path);
    g_free (escaped_path);

    evhtp_headers_add_header(req->headers_out,
                             evhtp_header_new("Location",
                                              url, 1, 1));
    /* Firefox expects Content-Length header. */
    evhtp_headers_add_header(req->headers_out,
                             evhtp_header_new("Content-Length",
                                              "0", 1, 1));
    evhtp_send_reply(req, EVHTP_RES_SEEOTHER);
}
Example #17
0
/**
 * Serves meta information in JSON about a hash.
 */
void route_meta(evhtp_request_t *req, void *arg) {
    evhtp_uri_t *uri = req->uri;
    char *res = uri->path->full;
    char *hash = "";
    res = strtok((char *) res, "/");
    while (res != NULL) {
        if (strlen(res) == 32) {
            hash = res;
            break;
        }
        res = strtok(NULL, "/");
    }

    char *color = malloc(sizeof (char)*7);
    make_color_hex(hash, color);

    int i[8][8];
    make_pattern(hash, i);

    char *pattern = malloc(sizeof (char)*146);
    sprintf(pattern, "[[%d,%d,%d,%d,%d,%d,%d,%d],"
            "[%d,%d,%d,%d,%d,%d,%d,%d],"
            "[%d,%d,%d,%d,%d,%d,%d,%d],"
            "[%d,%d,%d,%d,%d,%d,%d,%d],"
            "[%d,%d,%d,%d,%d,%d,%d,%d],"
            "[%d,%d,%d,%d,%d,%d,%d,%d],"
            "[%d,%d,%d,%d,%d,%d,%d,%d],"
            "[%d,%d,%d,%d,%d,%d,%d,%d]]",
            i[0][0], i[0][1], i[0][2], i[0][3], i[0][4], i[0][5], i[0][6], i[0][7],
            i[1][0], i[1][1], i[1][2], i[1][3], i[1][4], i[1][5], i[1][6], i[1][7],
            i[2][0], i[2][1], i[2][2], i[2][3], i[2][4], i[2][5], i[2][6], i[2][7],
            i[3][0], i[3][1], i[3][2], i[3][3], i[3][4], i[3][5], i[3][6], i[3][7],
            i[4][0], i[4][1], i[4][2], i[4][3], i[4][4], i[4][5], i[4][6], i[4][7],
            i[5][0], i[5][1], i[5][2], i[5][3], i[5][4], i[5][5], i[5][6], i[5][7],
            i[6][0], i[6][1], i[6][2], i[6][3], i[6][4], i[6][5], i[6][6], i[6][7],
            i[7][0], i[7][1], i[7][2], i[7][3], i[7][4], i[7][5], i[7][6], i[7][7]
            );
    pattern[145] = 0;

    evbuffer_add_printf(req->buffer_out, "{\"hash\":\"%s\",\"modified\":false,\"color\":\"%s\",\"pattern\":%s}", hash, color, pattern);
    free(color);
    free(pattern);
    evhtp_headers_add_header(req->headers_out,
            evhtp_header_new("Content-Type", "application/json", 0, 0));
    evhtp_send_reply(req, 200);
}
Example #18
0
static void
redirect_to_update_error (evhtp_request_t *req,
                          const char *repo_id,
                          const char *target_file,
                          int error_code)
{
    char *seahub_url, *escaped_path;
    char url[1024];

    seahub_url = seaf->session->base.service_url;
    escaped_path = g_uri_escape_string (target_file, NULL, FALSE);
    snprintf(url, 1024, "%s/repo/update_error/%s?p=%s&err=%d",
             seahub_url, repo_id, escaped_path, error_code);
    g_free (escaped_path);

    evhtp_headers_add_header(req->headers_out,
                             evhtp_header_new("Location",
                                              url, 0, 0));
    evhtp_send_reply(req, EVHTP_RES_FOUND);
}
Example #19
0
void send_file(evhtp_request_t* req, char* path)
{
	struct stat st;
	unsigned char data[1024];
	int fd;
	int n;
	evbuf_t* buf = NULL;
	
	if (stat(path, &st) < 0 || S_ISDIR(st.st_mode))
		goto file_error;
		
	fd = open(path, O_RDONLY);
	
	if (fd < 0)
		goto file_error;
		
	buf = evbuffer_new();
	
	evhtp_headers_add_header(req->headers_out,
								 evhtp_header_new("Content-Type", guess_content_type(path), 0, 0));
	
	evhtp_send_reply_chunk_start(req, EVHTP_RES_OK);
	do {
		n = read(fd, data, sizeof(data));
		evbuffer_add(buf, data, n);
		evhtp_send_reply_chunk(req, buf);
		evbuffer_drain(buf, -1);
	} while (n > 0);
	close(fd);
	
	evhtp_send_reply_chunk_end(req);
	evbuffer_free(buf);

	return;
	
file_error:
	evbuffer_add_printf(req->buffer_out, "ERROR:%s", path);
	evhtp_send_reply(req, EVHTP_RES_OK);		
}
Example #20
0
/**
 * @brief post_request_cb The callback function of a POST request to upload a image.
 *
 * @param req The request with image buffer.
 * @param arg It is not useful.
 */
void post_request_cb(evhtp_request_t *req, void *arg)
{
    int post_size = 0;
    char *buff = NULL;
    int err_no = 0;
    int ret_json = 1;

    evhtp_connection_t *ev_conn = evhtp_request_get_connection(req);
    struct sockaddr *saddr = ev_conn->saddr;
    struct sockaddr_in *ss = (struct sockaddr_in *)saddr;
    char address[16];

    const char *xff_address = evhtp_header_find(req->headers_in, "X-Forwarded-For");
    if(xff_address)
    {
        inet_aton(xff_address, &ss->sin_addr);
    }
    strncpy(address, inet_ntoa(ss->sin_addr), 16);

    int req_method = evhtp_request_get_method(req);
    if(req_method >= 16)
        req_method = 16;
    LOG_PRINT(LOG_DEBUG, "Method: %d", req_method);
    if(strcmp(method_strmap[req_method], "POST") != 0)
    {
        LOG_PRINT(LOG_DEBUG, "Request Method Not Support.");
        LOG_PRINT(LOG_INFO, "%s refuse post method", address);
        err_no = 2;
        goto err;
    }

    if(settings.up_access != NULL)
    {
        int acs = zimg_access_inet(settings.up_access, ss->sin_addr.s_addr);
        LOG_PRINT(LOG_DEBUG, "access check: %d", acs);
        if(acs == ZIMG_FORBIDDEN)
        {
            LOG_PRINT(LOG_DEBUG, "check access: ip[%s] forbidden!", address);
            LOG_PRINT(LOG_INFO, "%s refuse post forbidden", address);
            err_no = 3;
            goto forbidden;
        }
        else if(acs == ZIMG_ERROR)
        {
            LOG_PRINT(LOG_DEBUG, "check access: check ip[%s] failed!", address);
            LOG_PRINT(LOG_ERROR, "%s fail post access %s", address);
            err_no = 0;
            goto err;
        }
    }

    const char *content_len = evhtp_header_find(req->headers_in, "Content-Length");
    if(!content_len)
    {
        LOG_PRINT(LOG_DEBUG, "Get Content-Length error!");
        LOG_PRINT(LOG_ERROR, "%s fail post content-length", address);
        err_no = 5;
        goto err;
    }
    post_size = atoi(content_len);
    if(post_size <= 0)
    {
        LOG_PRINT(LOG_DEBUG, "Image Size is Zero!");
        LOG_PRINT(LOG_ERROR, "%s fail post empty", address);
        err_no = 5;
        goto err;
    }
    if(post_size > settings.max_size)
    {
        LOG_PRINT(LOG_DEBUG, "Image Size Too Large!");
        LOG_PRINT(LOG_ERROR, "%s fail post large", address);
        err_no = 7;
        goto err;
    }
    const char *content_type = evhtp_header_find(req->headers_in, "Content-Type");
    if(!content_type)
    {
        LOG_PRINT(LOG_DEBUG, "Get Content-Type error!");
        LOG_PRINT(LOG_ERROR, "%s fail post content-type", address);
        err_no = 6;
        goto err;
    }
	evbuf_t *buf;
    buf = req->buffer_in;
    buff = (char *)malloc(post_size);
    if(buff == NULL)
    {
        LOG_PRINT(LOG_DEBUG, "buff malloc failed!");
        LOG_PRINT(LOG_ERROR, "%s fail malloc buff", address);
        err_no = 0;
        goto err;
    }
    int rmblen, evblen;
    if(evbuffer_get_length(buf) <= 0)
    {
        LOG_PRINT(LOG_DEBUG, "Empty Request!");
        LOG_PRINT(LOG_ERROR, "%s fail post empty", address);
        err_no = 4;
        goto err;
    }
    while((evblen = evbuffer_get_length(buf)) > 0)
    {
        LOG_PRINT(LOG_DEBUG, "evblen = %d", evblen);
        rmblen = evbuffer_remove(buf, buff, evblen);
        LOG_PRINT(LOG_DEBUG, "rmblen = %d", rmblen);
        if(rmblen < 0)
        {
            LOG_PRINT(LOG_DEBUG, "evbuffer_remove failed!");
            LOG_PRINT(LOG_ERROR, "%s fail post parse", address);
            err_no = 4;
            goto err;
        }
    }
    if(strstr(content_type, "multipart/form-data") == NULL)
    {
        err_no = binary_parse(req, content_type, address, buff, post_size);
    }
    else
    {
        ret_json = 0;
        err_no = multipart_parse(req, content_type, address, buff, post_size);
    }
    if(err_no != -1)
    {
        goto err;
    }
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1));
    evhtp_send_reply(req, EVHTP_RES_OK);
    LOG_PRINT(LOG_DEBUG, "============post_request_cb() DONE!===============");
    goto done;

forbidden:
    json_return(req, err_no, NULL, 0);
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1));
    evhtp_send_reply(req, EVHTP_RES_OK);
    LOG_PRINT(LOG_DEBUG, "============post_request_cb() FORBIDDEN!===============");
    goto done;

err:
    if(ret_json == 0)
    {
        evbuffer_add_printf(req->buffer_out, "<h1>Upload Failed!</h1></body></html>"); 
        evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
    }
    else
    {
        json_return(req, err_no, NULL, 0);
    }
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1));
    evhtp_send_reply(req, EVHTP_RES_OK);
    LOG_PRINT(LOG_DEBUG, "============post_request_cb() ERROR!===============");

done:
    free(buff);
}
Example #21
0
int multipart_parse(evhtp_request_t *req, const char *content_type, const char *address, const char *buff, int post_size)
{
    int err_no = 0;
    char *boundary = NULL, *boundary_end = NULL;
    char *boundaryPattern = NULL;
    int boundary_len = 0;
    mp_arg_t *mp_arg = NULL;

    evbuffer_add_printf(req->buffer_out, 
            "<html>\n<head>\n"
            "<title>Upload Result</title>\n"
            "</head>\n"
            "<body>\n"
            );

    if(strstr(content_type, "boundary") == 0)
    {
        LOG_PRINT(LOG_DEBUG, "boundary NOT found!");
        LOG_PRINT(LOG_ERROR, "%s fail post parse", address);
        err_no = 6;
        goto done;
    }

    boundary = strchr(content_type, '=');
    boundary++;
    boundary_len = strlen(boundary);

    if(boundary[0] == '"') 
    {
        boundary++;
        boundary_end = strchr(boundary, '"');
        if (!boundary_end) 
        {
            LOG_PRINT(LOG_DEBUG, "Invalid boundary in multipart/form-data POST data");
            LOG_PRINT(LOG_ERROR, "%s fail post parse", address);
            err_no = 6;
            goto done;
        }
    } 
    else 
    {
        /* search for the end of the boundary */
        boundary_end = strpbrk(boundary, ",;");
    }
    if (boundary_end) 
    {
        boundary_end[0] = '\0';
        boundary_len = boundary_end-boundary;
    }

    LOG_PRINT(LOG_DEBUG, "boundary Find. boundary = %s", boundary);
    boundaryPattern = (char *)malloc(boundary_len + 3);
    if(boundaryPattern == NULL)
    {
        LOG_PRINT(LOG_DEBUG, "boundarypattern malloc failed!");
        LOG_PRINT(LOG_ERROR, "%s fail malloc", address);
        err_no = 0;
        goto done;
    }
    snprintf(boundaryPattern, boundary_len + 3, "--%s", boundary);
    LOG_PRINT(LOG_DEBUG, "boundaryPattern = %s, strlen = %d", boundaryPattern, (int)strlen(boundaryPattern));

    multipart_parser* parser = multipart_parser_init(boundaryPattern);
    if(!parser)
    {
        LOG_PRINT(LOG_DEBUG, "Multipart_parser Init Failed!");
        LOG_PRINT(LOG_ERROR, "%s fail post save", address);
        err_no = 0;
        goto done;
    }
    mp_arg = (mp_arg_t *)malloc(sizeof(mp_arg_t));
    if(!mp_arg)
    {
        LOG_PRINT(LOG_DEBUG, "Multipart_parser Arg Malloc Failed!");
        LOG_PRINT(LOG_ERROR, "%s fail post save", address);
        err_no = 0;
        goto done;
    }

    evthr_t *thread = get_request_thr(req);
    thr_arg_t *thr_arg = (thr_arg_t *)evthr_get_aux(thread);
    mp_arg->req = req;
    mp_arg->thr_arg = thr_arg;
    str_lcpy(mp_arg->address, address, 16);
    mp_arg->partno = 0;
    mp_arg->succno = 0;
    mp_arg->check_name = 0;
    multipart_parser_set_data(parser, mp_arg);
    multipart_parser_execute(parser, buff, post_size);
    multipart_parser_free(parser);

    if(mp_arg->succno == 0)
    {
        evbuffer_add_printf(req->buffer_out, "<h1>Upload Failed!</h1>\n");
    }

    evbuffer_add_printf(req->buffer_out, "</body>\n</html>\n");
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
    err_no = -1;

done:
    free(boundaryPattern);
    free(mp_arg);
    return err_no;
}
Example #22
0
/**
 * Serves the favicon file.
 */
void route_favicon(evhtp_request_t *req, void *arg) {
    evhtp_headers_add_header(req->headers_out,
            evhtp_header_new("Cache-Control", "max-age=90000, public", 0, 0));
    serve_static(req, "static/favicon.ico", "image/x-icon");
}
Example #23
0
/**
 * @brief post_request_cb The callback function of a POST request to upload a image.
 *
 * @param req The request with image buffer.
 * @param arg It is not useful.
 */
void post_request_cb(evhtp_request_t *req, void *arg)
{
    int post_size = 0;
    char *boundary = NULL, *boundary_end = NULL;
    int boundary_len = 0;
    char *fileName = NULL;
    char *boundaryPattern = NULL;
    char *buff = NULL;

    int req_method = evhtp_request_get_method(req);
    if(req_method >= 16)
        req_method = 16;
    LOG_PRINT(LOG_INFO, "Method: %d", req_method);
    if(strcmp(method_strmap[req_method], "POST") != 0)
    {
        LOG_PRINT(LOG_INFO, "Request Method Not Support.");
        goto err;
    }


    const char *content_len = evhtp_header_find(req->headers_in, "Content-Length");
    post_size = atoi(content_len);
    const char *content_type = evhtp_header_find(req->headers_in, "Content-Type");
    if(strstr(content_type, "multipart/form-data") == 0)
    {
        LOG_PRINT(LOG_ERROR, "POST form error!");
        goto err;
    }
    else if(strstr(content_type, "boundary") == 0)
    {
        LOG_PRINT(LOG_ERROR, "boundary NOT found!");
        goto err;
    }

    boundary = strchr(content_type, '=');
    boundary++;
    boundary_len = strlen(boundary);

    if (boundary[0] == '"') 
    {
        boundary++;
        boundary_end = strchr(boundary, '"');
        if (!boundary_end) 
        {
            LOG_PRINT(LOG_ERROR, "Invalid boundary in multipart/form-data POST data");
            goto err;
        }
    } 
    else 
    {
        /* search for the end of the boundary */
        boundary_end = strpbrk(boundary, ",;");
    }
    if (boundary_end) 
    {
        boundary_end[0] = '\0';
        boundary_len = boundary_end-boundary;
    }

    LOG_PRINT(LOG_INFO, "boundary Find. boundary = %s", boundary);
            
    /* 依靠evbuffer自己实现php处理函数 */
	evbuf_t *buf;
    buf = req->buffer_in;
    buff = (char *)malloc(post_size);
    int rmblen, evblen;
    int img_size = 0;

    if(evbuffer_get_length(buf) <= 0)
    {
        LOG_PRINT(LOG_ERROR, "Empty Request!");
        goto err;
    }

    while((evblen = evbuffer_get_length(buf)) > 0)
    {
        LOG_PRINT(LOG_INFO, "evblen = %d", evblen);
        rmblen = evbuffer_remove(buf, buff, evblen);
        LOG_PRINT(LOG_INFO, "rmblen = %d", rmblen);
        if(rmblen < 0)
        {
            LOG_PRINT(LOG_ERROR, "evbuffer_remove failed!");
            goto err;
        }
    }

    int start = -1, end = -1;
    const char *fileNamePattern = "filename=";
    const char *typePattern = "Content-Type";
    const char *quotePattern = "\"";
    const char *blankPattern = "\r\n";
    boundaryPattern = (char *)malloc(boundary_len + 4);
    sprintf(boundaryPattern, "\r\n--%s", boundary);
    LOG_PRINT(LOG_INFO, "boundaryPattern = %s, strlen = %d", boundaryPattern, (int)strlen(boundaryPattern));
    if((start = kmp(buff, post_size, fileNamePattern, strlen(fileNamePattern))) == -1)
    {
        LOG_PRINT(LOG_ERROR, "Content-Disposition Not Found!");
        goto err;
    }
    start += 9;
    if(buff[start] == '\"')
    {
        start++;
        if((end = kmp(buff+start, post_size-start, quotePattern, strlen(quotePattern))) == -1)
        {
            LOG_PRINT(LOG_ERROR, "quote \" Not Found!");
            goto err;
        }
    }
    else
    {
        if((end = kmp(buff+start, post_size-start, blankPattern, strlen(blankPattern))) == -1)
        {
            LOG_PRINT(LOG_ERROR, "quote \" Not Found!");
            goto err;
        }
    }
    fileName = (char *)malloc(end + 1);
    memcpy(fileName, buff+start, end);
    fileName[end] = '\0';
    LOG_PRINT(LOG_INFO, "fileName = %s", fileName);

    char fileType[32];
    if(get_type(fileName, fileType) == -1)
    {
        LOG_PRINT(LOG_ERROR, "Get Type of File[%s] Failed!", fileName);
        goto err;
    }
    if(is_img(fileType) != 1)
    {
        LOG_PRINT(LOG_ERROR, "fileType[%s] is Not Supported!", fileType);
        goto err;
    }

    end += start;

    if((start = kmp(buff+end, post_size-end, typePattern, strlen(typePattern))) == -1)
    {
        LOG_PRINT(LOG_ERROR, "Content-Type Not Found!");
        goto err;
    }
    start += end;
    LOG_PRINT(LOG_INFO, "start = %d", start);
    if((end =  kmp(buff+start, post_size-start, blankPattern, strlen(blankPattern))) == -1)
    {
        LOG_PRINT(LOG_ERROR, "Image Not complete!");
        goto err;
    }
    end += start;
    LOG_PRINT(LOG_INFO, "end = %d", end);
    start = end + 4;
    LOG_PRINT(LOG_INFO, "start = %d", start);
    if((end = kmp(buff+start, post_size-start, boundaryPattern, strlen(boundaryPattern))) == -1)
    {
        LOG_PRINT(LOG_ERROR, "Image Not complete!");
        goto err;
    }
    end += start;
    LOG_PRINT(LOG_INFO, "end = %d", end);
    img_size = end - start;


    LOG_PRINT(LOG_INFO, "post_size = %d", post_size);
    LOG_PRINT(LOG_INFO, "img_size = %d", img_size);
    if(img_size <= 0)
    {
        LOG_PRINT(LOG_ERROR, "Image Size is Zero!");
        goto err;
    }

    char md5sum[33];

    LOG_PRINT(LOG_INFO, "Begin to Save Image...");
    if(save_img(buff+start, img_size, md5sum) == -1)
    {
        LOG_PRINT(LOG_ERROR, "Image Save Failed!");
        goto err;
    }

    //libevhtp has bug with uri->authority->hostname, so zimg don't show hostname temporarily.
    //const char *host_name = req->uri->authority->hostname;
    //const int *host_port = req->uri->authority->port;
    //LOG_PRINT(LOG_INFO, "hostname: %s", req->uri->authority->hostname);
    //LOG_PRINT(LOG_INFO, "hostport: %d", host_port);
    evbuffer_add_printf(req->buffer_out, 
        "<html>\n<head>\n"
        "<title>Upload Successfully</title>\n"
        "</head>\n"
        "<body>\n"
        "<h1>MD5: %s</h1>\n"
        "Image upload successfully! You can get this image via this address:<br/><br/>\n"
        "http://yourhostname:%d/%s?w=width&h=height&g=isgray\n"
        "</body>\n</html>\n",
        md5sum, settings.port, md5sum
        );
    //evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", "zimg/1.0.0 (Unix) (OpenSUSE/Linux)", 0, 0));
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", server_name, 0, 0));
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
    evhtp_send_reply(req, EVHTP_RES_OK);
    LOG_PRINT(LOG_INFO, "============post_request_cb() DONE!===============");
    goto done;

err:
    evbuffer_add_printf(req->buffer_out, "<html><body><h1>Upload Failed!</h1></body><html>"); 
    //evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", "zimg/1.0.0 (Unix) (OpenSUSE/Linux)", 0, 0));
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", server_name, 0, 0));
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
    evhtp_send_reply(req, EVHTP_RES_200);
    LOG_PRINT(LOG_INFO, "============post_request_cb() ERROR!===============");

done:
    if(fileName)
        free(fileName);
    if(boundaryPattern)
        free(boundaryPattern);
    if(buff)
        free(buff);
}
Example #24
0
void wshtp_add_header(wshtp_conn_t *conn, const char *key, const char *val) {
    evhtp_headers_add_header(conn->reply.headers, evhtp_header_new(key, val, 1,1));
}
Example #25
0
static void ws_headers_add_header(evhtp_headers_t *headers, const char *key, const char *val) {
    evhtp_headers_add_header(headers, evhtp_header_new(key, val, 1, 1));
}
Example #26
0
/*
  Handle AJAX file upload.
  @return an array of json data, e.g. [{"name": "foo.txt"}]
 */
static void
upload_ajax_cb(evhtp_request_t *req, void *arg)
{
    RecvFSM *fsm = arg;
    SearpcClient *rpc_client = NULL;
    char *parent_dir;
    GError *error = NULL;
    int error_code = ERROR_INTERNAL;
    char *filenames_json, *tmp_files_json;

    evhtp_headers_add_header (req->headers_out,
                              evhtp_header_new("Access-Control-Allow-Headers",
                                               "x-requested-with, content-type, accept, origin, authorization", 1, 1));
    evhtp_headers_add_header (req->headers_out,
                              evhtp_header_new("Access-Control-Allow-Methods",
                                               "GET, POST, PUT, PATCH, DELETE, OPTIONS", 1, 1));
    evhtp_headers_add_header (req->headers_out,
                              evhtp_header_new("Access-Control-Allow-Origin",
                                               "*", 1, 1));
    evhtp_headers_add_header (req->headers_out,
                              evhtp_header_new("Access-Control-Max-Age",
                                               "86400", 1, 1));

    if (evhtp_request_get_method(req) == htp_method_OPTIONS) {
        /* If CORS preflight header, then create an empty body response (200 OK)
         * and return it.
         */
         evhtp_headers_add_header (req->headers_out,
                                   evhtp_header_new("Content-Type",
                                                    "text/html; charset=utf-8", 1, 1));         
         
         set_content_length_header (req);
         evhtp_send_reply (req, EVHTP_RES_OK);
         return;
    }

    /* After upload_headers_cb() returns an error, libevhtp may still
     * receive data from the web browser and call into this cb.
     * In this case fsm will be NULL.
     */
    if (!fsm || fsm->state == RECV_ERROR)
        return;

    if (!fsm->files) {
        seaf_warning ("[upload] No file uploaded.\n");
        set_content_length_header (req);
        evhtp_send_reply (req, EVHTP_RES_BADREQ);
        return;
    }

    parent_dir = g_hash_table_lookup (fsm->form_kvs, "parent_dir");
    if (!parent_dir) {
        seaf_warning ("[upload] No parent dir given.\n");
        evbuffer_add_printf(req->buffer_out, "Invalid URL.\n");
        set_content_length_header (req);
        evhtp_send_reply (req, EVHTP_RES_BADREQ);
        return;
    }

    if (!check_tmp_file_list (fsm->files, &error_code))
        goto error;

    rpc_client = ccnet_create_pooled_rpc_client (seaf->client_pool,
                                                 NULL,
                                                 "seafserv-threaded-rpcserver");

    if (seafile_check_quota (rpc_client, fsm->repo_id, NULL) < 0) {
        seaf_warning ("[upload] Out of quota.\n");
        error_code = ERROR_QUOTA;
        goto error;
    }

    filenames_json = file_list_to_json (fsm->filenames);
    tmp_files_json = file_list_to_json (fsm->files);

    seafile_post_multi_files (rpc_client,
                              fsm->repo_id,
                              parent_dir,
                              filenames_json,
                              tmp_files_json,
                              fsm->user,
                              &error);
    g_free (filenames_json);
    g_free (tmp_files_json);
    if (error) {
        if (error->code == POST_FILE_ERR_FILENAME) {
            error_code = ERROR_FILENAME;
            seaf_warning ("[upload] Bad filename.\n");
        }
        g_clear_error (&error);
        goto error;
    }

    ccnet_rpc_client_free (rpc_client);

    GString *res_buf = g_string_new (NULL);
    GList *ptr;

    g_string_append (res_buf, "[");
    for (ptr = fsm->filenames; ptr; ptr = ptr->next) {
        char *filename = ptr->data;
        if (ptr->next)
            g_string_append_printf (res_buf, "{\"name\": \"%s\"}, ", filename);
        else
            g_string_append_printf (res_buf, "{\"name\": \"%s\"}", filename);
    }
    g_string_append (res_buf, "]");

    evbuffer_add (req->buffer_out, res_buf->str, res_buf->len);
    g_string_free (res_buf, TRUE);

    set_content_length_header (req);
    evhtp_send_reply (req, EVHTP_RES_OK);
    return;

error:
    if (rpc_client)
        ccnet_rpc_client_free (rpc_client);

    switch (error_code) {
    case ERROR_FILENAME:
        evbuffer_add_printf(req->buffer_out, "Invalid filename.\n");
        set_content_length_header (req);
        evhtp_send_reply (req, SEAF_HTTP_RES_BADFILENAME);
        break;
    case ERROR_EXISTS:
        evbuffer_add_printf(req->buffer_out, "File already exists.\n");
        set_content_length_header (req);
        evhtp_send_reply (req, SEAF_HTTP_RES_EXISTS);
        break;
    case ERROR_SIZE:
        evbuffer_add_printf(req->buffer_out, "File size is too large.\n");
        set_content_length_header (req);
        evhtp_send_reply (req, SEAF_HTTP_RES_TOOLARGE);
        break;
    case ERROR_QUOTA:
        evbuffer_add_printf(req->buffer_out, "Out of quota.\n");
        set_content_length_header (req);
        evhtp_send_reply (req, SEAF_HTTP_RES_NOQUOTA);
        break;
    case ERROR_RECV:
    case ERROR_INTERNAL:
        set_content_length_header (req);
        evhtp_send_reply (req, EVHTP_RES_SERVERR);
        break;
    }
}
Example #27
0
/**
 * @brief send_document_cb The callback function of get a image request.
 *
 * @param req The request with a list of params and the md5 of image.
 * @param arg It is not useful.
 */
void send_document_cb(evhtp_request_t *req, void *arg)
{
    char *md5 = NULL;
	size_t len;
    zimg_req_t *zimg_req = NULL;
	char *buff = NULL;

    int req_method = evhtp_request_get_method(req);
    if(req_method >= 16)
        req_method = 16;
    LOG_PRINT(LOG_INFO, "Method: %d", req_method);
    if(strcmp(method_strmap[req_method], "POST") == 0)
    {
        LOG_PRINT(LOG_INFO, "POST Request.");
        post_request_cb(req, NULL);
        return;
    }
	else if(strcmp(method_strmap[req_method], "GET") != 0)
    {
        LOG_PRINT(LOG_INFO, "Request Method Not Support.");
        goto err;
    }


	const char *uri;
	uri = req->uri->path->full;
	const char *rfull = req->uri->path->full;
	const char *rpath = req->uri->path->path;
	const char *rfile= req->uri->path->file;
	LOG_PRINT(LOG_INFO, "uri->path->full: %s",  rfull);
	LOG_PRINT(LOG_INFO, "uri->path->path: %s",  rpath);
	LOG_PRINT(LOG_INFO, "uri->path->file: %s",  rfile);

    if(strlen(uri) == 1 && uri[0] == '/')
    {
        LOG_PRINT(LOG_INFO, "Root Request.");
        int fd = -1;
        struct stat st;
        if((fd = open(settings.root_path, O_RDONLY)) == -1)
        {
            LOG_PRINT(LOG_WARNING, "Root_page Open Failed. Return Default Page.");
            evbuffer_add_printf(req->buffer_out, "<html>\n<body>\n<h1>\nWelcome To zimg World!</h1>\n</body>\n</html>\n");
        }
        else
        {
            if (fstat(fd, &st) < 0)
            {
                /* Make sure the length still matches, now that we
                 * opened the file :/ */
                LOG_PRINT(LOG_WARNING, "Root_page Length fstat Failed. Return Default Page.");
                evbuffer_add_printf(req->buffer_out, "<html>\n<body>\n<h1>\nWelcome To zimg World!</h1>\n</body>\n</html>\n");
            }
            else
            {
                evbuffer_add_file(req->buffer_out, fd, 0, st.st_size);
            }
        }
        evbuffer_add_printf(req->buffer_out, "<html>\n </html>\n");
        //evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", "zimg/1.0.0 (Unix) (OpenSUSE/Linux)", 0, 0));
        evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", server_name, 0, 0));
        evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
        evhtp_send_reply(req, EVHTP_RES_OK);
        LOG_PRINT(LOG_INFO, "============send_document_cb() DONE!===============");
        goto done;
    }

    if(strstr(uri, "favicon.ico"))
    {
        LOG_PRINT(LOG_INFO, "favicon.ico Request, Denied.");
        //evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", "zimg/1.0.0 (Unix) (OpenSUSE/Linux)", 0, 0));
        evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", server_name, 0, 0));
        evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
        evhtp_send_reply(req, EVHTP_RES_OK);
        goto done;
    }
	LOG_PRINT(LOG_INFO, "Got a GET request for <%s>",  uri);

	/* Don't allow any ".."s in the path, to avoid exposing stuff outside
	 * of the docroot.  This test is both overzealous and underzealous:
	 * it forbids aceptable paths like "/this/one..here", but it doesn't
	 * do anything to prevent symlink following." */
	if (strstr(uri, ".."))
		goto err;

    md5 = (char *)malloc(strlen(uri) + 1);
    if(uri[0] == '/')
        strcpy(md5, uri+1);
    else
        strcpy(md5, uri);
	LOG_PRINT(LOG_INFO, "md5 of request is <%s>",  md5);
    if(is_md5(md5) == -1)
    {
        LOG_PRINT(LOG_WARNING, "Url is Not a zimg Request.");
        goto err;
    }
	/* This holds the content we're sending. */

    int width, height, proportion, gray;
    evhtp_kvs_t *params;
    params = req->uri->query;
    if(!params)
    {
        width = 0;
        height = 0;
        proportion = 1;
        gray = 0;
    }
    else
    {
        const char *str_w, *str_h;
        str_w = evhtp_kv_find(params, "w");
        if(str_w == NULL)
            str_w = "0";
        str_h = evhtp_kv_find(params, "h");
        if(str_h == NULL)
            str_h = "0";
        LOG_PRINT(LOG_INFO, "w() = %s; h() = %s;", str_w, str_h);
        if(strcmp(str_w, "g") == 0 && strcmp(str_h, "w") == 0)
        {
            LOG_PRINT(LOG_INFO, "Love is Eternal.");
            evbuffer_add_printf(req->buffer_out, "<html>\n <head>\n"
                "  <title>Love is Eternal</title>\n"
                " </head>\n"
                " <body>\n"
                "  <h1>Single1024</h1>\n"
                "Since 2008-12-22, there left no room in my heart for another one.</br>\n"
                "</body>\n</html>\n"
                );
            //evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", "zimg/1.0.0 (Unix) (OpenSUSE/Linux)", 0, 0));
            evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", server_name, 0, 0));
            evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
            evhtp_send_reply(req, EVHTP_RES_OK);
            LOG_PRINT(LOG_INFO, "============send_document_cb() DONE!===============");
            goto done;
        }
        else
        {
            width = atoi(str_w);
            height = atoi(str_h);
            const char *str_p = evhtp_kv_find(params, "p");
            const char *str_g = evhtp_kv_find(params, "g");
            if(str_p)
                proportion = atoi(str_p);
            else
                proportion = 1;
            if(str_g)
                gray = atoi(str_g);
            else
                gray = 0;
        }
    }

    zimg_req = (zimg_req_t *)malloc(sizeof(zimg_req_t)); 
    zimg_req -> md5 = md5;
    zimg_req -> width = width;
    zimg_req -> height = height;
    zimg_req -> proportion = proportion;
    zimg_req -> gray = gray;

    int get_img_rst = get_img(zimg_req, &buff,  &len);


    if(get_img_rst == -1)
    {
        LOG_PRINT(LOG_ERROR, "zimg Requset Get Image[MD5: %s] Failed!", zimg_req->md5);
        goto err;
    }

    LOG_PRINT(LOG_INFO, "get buffer length: %d", len);
    evbuffer_add(req->buffer_out, buff, len);

    LOG_PRINT(LOG_INFO, "Got the File!");
    //evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", "zimg/1.0.0 (Unix) (OpenSUSE/Linux)", 0, 0));
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", server_name, 0, 0));
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "image/jpeg", 0, 0));
    evhtp_send_reply(req, EVHTP_RES_OK);
    LOG_PRINT(LOG_INFO, "============send_document_cb() DONE!===============");


    if(get_img_rst == 2)
    {
        if(new_img(buff, len, zimg_req->rsp_path) == -1)
        {
            LOG_PRINT(LOG_WARNING, "New Image[%s] Save Failed!", zimg_req->rsp_path);
        }
    }
    goto done;

err:
    evbuffer_add_printf(req->buffer_out, "<html><body><h1>404 Not Found!</h1></body></html>");
    //evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", "zimg/1.0.0 (Unix) (OpenSUSE/Linux)", 0, 0));
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", server_name, 0, 0));
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
    evhtp_send_reply(req, EVHTP_RES_NOTFOUND);
    LOG_PRINT(LOG_INFO, "============send_document_cb() ERROR!===============");

done:
	if(buff)
		free(buff);
    if(zimg_req)
    {
        if(zimg_req->md5)
            free(zimg_req->md5);
        if(zimg_req->rsp_path)
            free(zimg_req->rsp_path);
        free(zimg_req);
    }
}
Example #28
0
/**
 * @brief get_request_cb The callback function of get a image request.
 *
 * @param req The request with a list of params and the md5 of image.
 * @param arg It is not useful.
 */
void get_request_cb(evhtp_request_t *req, void *arg)
{
    char *md5 = NULL, *fmt = NULL, *type = NULL;
    zimg_req_t *zimg_req = NULL;
	char *buff = NULL;
	size_t len;

    evhtp_connection_t *ev_conn = evhtp_request_get_connection(req);
    struct sockaddr *saddr = ev_conn->saddr;
    struct sockaddr_in *ss = (struct sockaddr_in *)saddr;
    char address[16];

    const char *xff_address = evhtp_header_find(req->headers_in, "X-Forwarded-For");
    if(xff_address)
    {
        inet_aton(xff_address, &ss->sin_addr);
    }
    strncpy(address, inet_ntoa(ss->sin_addr), 16);

    int req_method = evhtp_request_get_method(req);
    if(req_method >= 16)
        req_method = 16;
    LOG_PRINT(LOG_DEBUG, "Method: %d", req_method);
    if(strcmp(method_strmap[req_method], "POST") == 0)
    {
        LOG_PRINT(LOG_DEBUG, "POST Request.");
        post_request_cb(req, NULL);
        return;
    }
	else if(strcmp(method_strmap[req_method], "GET") != 0)
    {
        LOG_PRINT(LOG_DEBUG, "Request Method Not Support.");
        LOG_PRINT(LOG_INFO, "%s refuse method", address);
        goto err;
    }

    if(settings.down_access != NULL)
    {
        int acs = zimg_access_inet(settings.down_access, ss->sin_addr.s_addr);
        LOG_PRINT(LOG_DEBUG, "access check: %d", acs);

        if(acs == ZIMG_FORBIDDEN)
        {
            LOG_PRINT(LOG_DEBUG, "check access: ip[%s] forbidden!", address);
            LOG_PRINT(LOG_INFO, "%s refuse get forbidden", address);
            goto forbidden;
        }
        else if(acs == ZIMG_ERROR)
        {
            LOG_PRINT(LOG_DEBUG, "check access: check ip[%s] failed!", address);
            LOG_PRINT(LOG_ERROR, "%s fail get access", address);
            goto err;
        }
    }

	const char *uri;
	uri = req->uri->path->full;

    if(strlen(uri) == 1 && uri[0] == '/')
    {
        LOG_PRINT(LOG_DEBUG, "Root Request.");
        int fd = -1;
        struct stat st;
        if((fd = open(settings.root_path, O_RDONLY)) == -1)
        {
            LOG_PRINT(LOG_DEBUG, "Root_page Open Failed. Return Default Page.");
            evbuffer_add_printf(req->buffer_out, "<html>\n<body>\n<h1>\nWelcome To zimg World!</h1>\n</body>\n</html>\n");
        }
        else
        {
            if (fstat(fd, &st) < 0)
            {
                /* Make sure the length still matches, now that we
                 * opened the file :/ */
                LOG_PRINT(LOG_DEBUG, "Root_page Length fstat Failed. Return Default Page.");
                evbuffer_add_printf(req->buffer_out, "<html>\n<body>\n<h1>\nWelcome To zimg World!</h1>\n</body>\n</html>\n");
            }
            else
            {
                evbuffer_add_file(req->buffer_out, fd, 0, st.st_size);
            }
        }
        //evbuffer_add_printf(req->buffer_out, "<html>\n </html>\n");
        evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1));
        evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
        evhtp_send_reply(req, EVHTP_RES_OK);
        LOG_PRINT(LOG_DEBUG, "============get_request_cb() DONE!===============");
        LOG_PRINT(LOG_INFO, "%s succ root page", address);
        goto done;
    }

    if(strstr(uri, "favicon.ico"))
    {
        LOG_PRINT(LOG_DEBUG, "favicon.ico Request, Denied.");
        evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1));
        evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
        zimg_headers_add(req, settings.headers);
        evhtp_send_reply(req, EVHTP_RES_OK);
        goto done;
    }
	LOG_PRINT(LOG_DEBUG, "Got a GET request for <%s>",  uri);

	/* Don't allow any ".."s in the path, to avoid exposing stuff outside
	 * of the docroot.  This test is both overzealous and underzealous:
	 * it forbids aceptable paths like "/this/one..here", but it doesn't
	 * do anything to prevent symlink following." */
	if (strstr(uri, ".."))
    {
        LOG_PRINT(LOG_DEBUG, "attempt to upper dir!");
        LOG_PRINT(LOG_INFO, "%s refuse directory", address);
		goto forbidden;
    }

    size_t md5_len = strlen(uri) + 1;
    md5 = (char *)malloc(md5_len);
    if(md5 == NULL)
    {
        LOG_PRINT(LOG_DEBUG, "md5 malloc failed!");
        LOG_PRINT(LOG_ERROR, "%s fail malloc", address);
        goto err;
    }
    if(uri[0] == '/')
        str_lcpy(md5, uri+1, md5_len);
    else
        str_lcpy(md5, uri, md5_len);
	LOG_PRINT(LOG_DEBUG, "md5 of request is <%s>",  md5);
    if(is_md5(md5) == -1)
    {
        LOG_PRINT(LOG_DEBUG, "Url is Not a zimg Request.");
        LOG_PRINT(LOG_INFO, "%s refuse url illegal", address);
        goto err;
    }
	/* This holds the content we're sending. */

    evthr_t *thread = get_request_thr(req);
    thr_arg_t *thr_arg = (thr_arg_t *)evthr_get_aux(thread);

    int width, height, proportion, gray, x, y, rotate, quality, sv;
    width = 0;
    height = 0;
    proportion = 1;
    gray = 0;
    x = -1;
    y = -1;
    rotate = 0;
    quality = 0;
    sv = 0;

    evhtp_kvs_t *params;
    params = req->uri->query;
    if(params != NULL)
    {
        if(settings.disable_args != 1)
        {
            const char *str_w = evhtp_kv_find(params, "w");
            const char *str_h = evhtp_kv_find(params, "h");
            width = (str_w) ? atoi(str_w) : 0;
            height = (str_h) ? atoi(str_h) : 0;

            const char *str_p = evhtp_kv_find(params, "p");
            proportion = (str_p) ? atoi(str_p) : 1;

            const char *str_g = evhtp_kv_find(params, "g");
            gray = (str_g) ? atoi(str_g) : 0;

            const char *str_x = evhtp_kv_find(params, "x");
            const char *str_y = evhtp_kv_find(params, "y");
            x = (str_x) ? atoi(str_x) : -1;
            y = (str_y) ? atoi(str_y) : -1;

            if(x != -1 || y != -1)
            {
                proportion = 1;
            }

            const char *str_r = evhtp_kv_find(params, "r");
            rotate = (str_r) ? atoi(str_r) : 0;

            const char *str_q = evhtp_kv_find(params, "q");
            quality = (str_q) ? atoi(str_q) : 0;

            const char *str_f = evhtp_kv_find(params, "f");
            if(str_f)
            {
                size_t fmt_len = strlen(str_f) + 1;
                fmt = (char *)malloc(fmt_len);
                if(fmt != NULL)
                    str_lcpy(fmt, str_f, fmt_len);
                LOG_PRINT(LOG_DEBUG, "fmt = %s", fmt);
            }
        }

        if(settings.disable_type != 1)
        {
            const char *str_t = evhtp_kv_find(params, "t");
            if(str_t)
            {
                size_t type_len = strlen(str_t) + 1;
                type = (char *)malloc(type_len);
                if(type != NULL)
                    str_lcpy(type, str_t, type_len);
                LOG_PRINT(LOG_DEBUG, "type = %s", type);
            }
        }
    }
    else
    {
        sv = 1;
    }

    quality = (quality != 0 ? quality : settings.quality);
    zimg_req = (zimg_req_t *)malloc(sizeof(zimg_req_t)); 
    if(zimg_req == NULL)
    {
        LOG_PRINT(LOG_DEBUG, "zimg_req malloc failed!");
        LOG_PRINT(LOG_ERROR, "%s fail malloc", address);
        goto err;
    }
    zimg_req -> md5 = md5;
    zimg_req -> type = type;
    zimg_req -> width = width;
    zimg_req -> height = height;
    zimg_req -> proportion = proportion;
    zimg_req -> gray = gray;
    zimg_req -> x = x;
    zimg_req -> y = y;
    zimg_req -> rotate = rotate;
    zimg_req -> quality = quality;
    zimg_req -> fmt = (fmt != NULL ? fmt : settings.format);
    zimg_req -> sv = sv;
    zimg_req -> thr_arg = thr_arg;

    int get_img_rst = -1;
    get_img_rst = settings.get_img(zimg_req, req);

    if(get_img_rst == -1)
    {
        LOG_PRINT(LOG_DEBUG, "zimg Requset Get Image[MD5: %s] Failed!", zimg_req->md5);
        if(type)
            LOG_PRINT(LOG_ERROR, "%s fail pic:%s t:%s", address, md5, type);
        else
            LOG_PRINT(LOG_ERROR, "%s fail pic:%s w:%d h:%d p:%d g:%d x:%d y:%d r:%d q:%d f:%s",
                address, md5, width, height, proportion, gray, x, y, rotate, quality, zimg_req->fmt); 
        goto err;
    }
    if(get_img_rst == 2)
    {
        LOG_PRINT(LOG_DEBUG, "Etag Matched Return 304 EVHTP_RES_NOTMOD.");
        if(type)
            LOG_PRINT(LOG_INFO, "%s succ 304 pic:%s t:%s", address, md5, type);
        else
            LOG_PRINT(LOG_INFO, "%s succ 304 pic:%s w:%d h:%d p:%d g:%d x:%d y:%d r:%d q:%d f:%s",
                address, md5, width, height, proportion, gray, x, y, rotate, quality, zimg_req->fmt); 
        evhtp_send_reply(req, EVHTP_RES_NOTMOD);
        goto done;
    }

    len = evbuffer_get_length(req->buffer_out);
    LOG_PRINT(LOG_DEBUG, "get buffer length: %d", len);

    LOG_PRINT(LOG_DEBUG, "Got the File!");
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1));
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "image/jpeg", 0, 0));
    zimg_headers_add(req, settings.headers);
    evhtp_send_reply(req, EVHTP_RES_OK);
    if(type)
        LOG_PRINT(LOG_INFO, "%s succ pic:%s t:%s size:%d", address, md5, type, len); 
    else
        LOG_PRINT(LOG_INFO, "%s succ pic:%s w:%d h:%d p:%d g:%d x:%d y:%d r:%d q:%d f:%s size:%d", 
                address, md5, width, height, proportion, gray, x, y, rotate, quality, zimg_req->fmt, 
                len);
    LOG_PRINT(LOG_DEBUG, "============get_request_cb() DONE!===============");
    goto done;

forbidden:
    evbuffer_add_printf(req->buffer_out, "<html><body><h1>403 Forbidden!</h1></body></html>"); 
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1));
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
    evhtp_send_reply(req, EVHTP_RES_FORBIDDEN);
    LOG_PRINT(LOG_DEBUG, "============get_request_cb() FORBIDDEN!===============");
    goto done;

err:
    evbuffer_add_printf(req->buffer_out, "<html><body><h1>404 Not Found!</h1></body></html>");
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1));
    evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
    evhtp_send_reply(req, EVHTP_RES_NOTFOUND);
    LOG_PRINT(LOG_DEBUG, "============get_request_cb() ERROR!===============");

done:
    free(fmt);
    free(md5);
    free(type);
    free(zimg_req);
    free(buff);
}
Example #29
0
static evbuffer *
_evhtp_create_reply(evhtp_request_t * request, evhtp_res code) {
    evbuffer * buf = evbuffer_new();

    if (evbuffer_get_length(request->buffer_out) && request->chunked == 0) {
        /* add extra headers (like content-length/type) if not already present */

        if (!evhtp_header_find(request->headers_out, "Content-Length")) {
			std::ostringstream oss;
			oss<<evbuffer_get_length(request->buffer_out);
			std::string lstr=oss.str();      

            evhtp_headers_add_header(request->headers_out,
                                     evhtp_header_new("Content-Length", lstr.c_str(), 0, 1));
        }

		if (!evhtp_header_find(request->headers_out, "Server")) {
			  evhtp_headers_add_header(request->headers_out,
                                     evhtp_header_new("Server", "nginx/1.1.0", 0, 0));
		}

        if (!evhtp_header_find(request->headers_out, "Content-Type")) {
            evhtp_headers_add_header(request->headers_out,
                                     evhtp_header_new("Content-Type", "text/plain", 0, 0));
        }
    } else {
        if (!evhtp_header_find(request->headers_out, "Content-Length")) {
            const char * chunked = evhtp_header_find(request->headers_out,
                                                     "transfer-encoding");

            if (!chunked || !strstr(chunked, "chunked")) {
                evhtp_headers_add_header(request->headers_out,
                                         evhtp_header_new("Content-Length", "0", 0, 0));
            }
        }
    }


    /* add the proper keep-alive type headers based on http version */
    switch (request->proto) {
        case EVHTP_PROTO_11:
            if (request->keepalive == 0) {
                /* protocol is HTTP/1.1 but client wanted to close */
                evhtp_headers_add_header(request->headers_out,
                                         evhtp_header_new("Connection", "close", 0, 0));
            }
            break;
        case EVHTP_PROTO_10:
            if (request->keepalive == 1) {
                /* protocol is HTTP/1.0 and clients wants to keep established */
                evhtp_headers_add_header(request->headers_out,
                                         evhtp_header_new("Connection", "keep-alive", 0, 0));
            }
            break;
        default:
            /* this sometimes happens when a response is made but paused before
             * the method has been parsed */
			request->conn->parser->set_major(1);
			request->conn->parser->set_minor(0);
            break;
    } /* switch */

    /* add the status line */
    evbuffer_add_printf(buf, "HTTP/%d.%d %d %s\r\n",
		request->conn->parser->get_major(),
		request->conn->parser->get_minor(),
		code, StatusCodeManager::instance().status_code_to_str(code));

    evhtp_headers_for_each(request->headers_out, _evhtp_create_headers, buf);
    evbuffer_add_reference(buf, "\r\n", 2, NULL, NULL);

    if (evbuffer_get_length(request->buffer_out)) {
        evbuffer_add_buffer(buf, request->buffer_out);
    }

    return buf;
}     /* _evhtp_create_reply */
Example #30
0
/**
 * @brief admin_request_cb the callback function of admin requests
 *
 * @param req the evhtp request
 * @param arg the arg of request
 */
void admin_request_cb(evhtp_request_t *req, void *arg)
{
    char md5[33];

    evhtp_connection_t *ev_conn = evhtp_request_get_connection(req);
    struct sockaddr *saddr = ev_conn->saddr;
    struct sockaddr_in *ss = (struct sockaddr_in *)saddr;
    char address[16];

    const char *xff_address = evhtp_header_find(req->headers_in, "X-Forwarded-For");
    if(xff_address)
    {
        inet_aton(xff_address, &ss->sin_addr);
    }
    strncpy(address, inet_ntoa(ss->sin_addr), 16);

    int req_method = evhtp_request_get_method(req);
    if(req_method >= 16)
        req_method = 16;
    LOG_PRINT(LOG_DEBUG, "Method: %d", req_method);
    if(strcmp(method_strmap[req_method], "POST") == 0)
    {
        LOG_PRINT(LOG_DEBUG, "POST Request.");
        post_request_cb(req, NULL);
        return;
    }
	else if(strcmp(method_strmap[req_method], "GET") != 0)
    {
        LOG_PRINT(LOG_DEBUG, "Request Method Not Support.");
        LOG_PRINT(LOG_INFO, "%s refuse method", address);
        goto err;
    }

    if(settings.admin_access != NULL)
    {
        int acs = zimg_access_inet(settings.admin_access, ss->sin_addr.s_addr);
        LOG_PRINT(LOG_DEBUG, "access check: %d", acs);

        if(acs == ZIMG_FORBIDDEN)
        {
            LOG_PRINT(LOG_DEBUG, "check access: ip[%s] forbidden!", address);
            LOG_PRINT(LOG_INFO, "%s refuse admin forbidden", address);
            goto forbidden;
        }
        else if(acs == ZIMG_ERROR)
        {
            LOG_PRINT(LOG_DEBUG, "check access: check ip[%s] failed!", address);
            LOG_PRINT(LOG_ERROR, "%s fail admin access", address);
            goto err;
        }
    }

	const char *uri;
	uri = req->uri->path->full;

    if(strstr(uri, "favicon.ico"))
    {
        LOG_PRINT(LOG_DEBUG, "favicon.ico Request, Denied.");
        evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1));
        evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
        zimg_headers_add(req, settings.headers);
        evhtp_send_reply(req, EVHTP_RES_OK);
        return;
    }

	LOG_PRINT(LOG_DEBUG, "Got a Admin request for <%s>",  uri);
    int t;
    evhtp_kvs_t *params;
    params = req->uri->query;
    if(!params)
    {
        LOG_PRINT(LOG_DEBUG, "Admin Root Request.");
        int fd = -1;
        struct stat st;
        //TODO: use admin_path
        if((fd = open(settings.admin_path, O_RDONLY)) == -1)
        {
            LOG_PRINT(LOG_DEBUG, "Admin_page Open Failed. Return Default Page.");
            evbuffer_add_printf(req->buffer_out, "<html>\n<body>\n<h1>\nWelcome To zimg Admin!</h1>\n</body>\n</html>\n");
        }
        else
        {
            if (fstat(fd, &st) < 0)
            {
                /* Make sure the length still matches, now that we
                 * opened the file :/ */
                LOG_PRINT(LOG_DEBUG, "Root_page Length fstat Failed. Return Default Page.");
                evbuffer_add_printf(req->buffer_out, "<html>\n<body>\n<h1>\nWelcome To zimg Admin!</h1>\n</body>\n</html>\n");
            }
            else
            {
                evbuffer_add_file(req->buffer_out, fd, 0, st.st_size);
            }
        }
        //evbuffer_add_printf(req->buffer_out, "<html>\n </html>\n");
        evhtp_headers_add_header(req->headers_out, evhtp_header_new("Server", settings.server_name, 0, 1));
        evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
        evhtp_send_reply(req, EVHTP_RES_OK);
        LOG_PRINT(LOG_DEBUG, "============admin_request_cb() DONE!===============");
        LOG_PRINT(LOG_INFO, "%s succ admin root page", address);
        return;
    }
    else
    {
        const char *str_md5, *str_t;
        str_md5 = evhtp_kv_find(params, "md5");
        if(str_md5 == NULL)
        {
            LOG_PRINT(LOG_DEBUG, "md5() = NULL return");
            goto err;
        }

        str_lcpy(md5, str_md5, sizeof(md5));
        if(is_md5(md5) == -1)
        {
            LOG_PRINT(LOG_DEBUG, "Admin Request MD5 Error.");
            LOG_PRINT(LOG_INFO, "%s refuse admin url illegal", address);
            goto err;
        }
        str_t = evhtp_kv_find(params, "t");
        LOG_PRINT(LOG_DEBUG, "md5() = %s; t() = %s;", str_md5, str_t);
        t = (str_t) ? atoi(str_t) : 0;
    }

    evthr_t *thread = get_request_thr(req);
    thr_arg_t *thr_arg = (thr_arg_t *)evthr_get_aux(thread);

    int admin_img_rst = -1;
    admin_img_rst = settings.admin_img(req, thr_arg, md5, t);

    if(admin_img_rst == -1)
    {
        evbuffer_add_printf(req->buffer_out, 
            "<html><body><h1>Admin Command Failed!</h1> \
            <p>MD5: %s</p> \
            <p>Command Type: %d</p> \
            <p>Command Failed.</p> \
            </body></html>",
            md5, t);
        LOG_PRINT(LOG_ERROR, "%s fail admin pic:%s t:%d", address, md5, t); 
        evhtp_headers_add_header(req->headers_out, evhtp_header_new("Content-Type", "text/html", 0, 0));
    }