diff --git a/src/url.c b/src/url.c new file mode 100755 index 0000000..4bd3936 --- /dev/null +++ b/src/url.c @@ -0,0 +1,97 @@ + #include + #include + #include + #include + + #include "url.h" + + static unsigned char hexchars[] = "0123456789ABCDEF"; + + static int zimg_htoi(char *s) + { + int value; + int c; + + c = ((unsigned char *)s)[0]; + if (isupper(c)) + c = tolower(c); + value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16; + + c = ((unsigned char *)s)[1]; + if (isupper(c)) + c = tolower(c); + value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10; + + return (value); + } + + + char *zimg_url_encode(char const *s, int len, int *new_length) + { + register unsigned char c; + unsigned char *to, *start; + unsigned char const *from, *end; + + from = (unsigned char *)s; + end = (unsigned char *)s + len; + start = to = (unsigned char *) calloc(1, 3*len+1); + + while (from < end) + { + c = *from++; + + if (c == ' ') + { + *to++ = '+'; + } + else if ((c < '0' && c != '-' && c != '.') || + (c < 'A' && c > '9') || + (c > 'Z' && c < 'a' && c != '_') || + (c > 'z')) + { + to[0] = '%'; + to[1] = hexchars[c >> 4]; + to[2] = hexchars[c & 15]; + to += 3; + } + else + { + *to++ = c; + } + } + *to = 0; + if (new_length) + { + *new_length = to - start; + } + return (char *) start; + } + + + int zimg_url_decode(char *str, int len) + { + char *dest = str; + char *data = str; + + while (len--) + { + if (*data == '+') + { + *dest = ' '; + } + else if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) && isxdigit((int) *(data + 2))) + { + *dest = (char) zimg_htoi(data + 1); + data += 2; + len -= 2; + } + else + { + *dest = *data; + } + data++; + dest++; + } + *dest = '\0'; + return dest - str; + } diff --git a/src/url.h b/src/url.h new file mode 100755 index 0000000..3651b78 --- /dev/null +++ b/src/url.h @@ -0,0 +1,15 @@ +#ifndef URL_H +#define URL_H + +#ifdef __cplusplus +extern "C" { +#endif + +int zimg_url_decode(char *str, int len); +char *zimg_url_encode(char const *s, int len, int *new_length); + +#ifdef __cplusplus +} +#endif + +#endif /* URL_H */ diff --git a/src/zcommon.h b/src/zcommon.h old mode 100644 new mode 100755 index 4049bd7..786684c --- a/src/zcommon.h +++ b/src/zcommon.h @@ -65,6 +65,7 @@ typedef struct zimg_req_s { char *fmt; int sv; thr_arg_t *thr_arg; + char file_schema[1024]; } zimg_req_t; struct setting{ @@ -92,7 +93,6 @@ struct setting{ char admin_path[512]; int disable_args; int disable_type; - int disable_zoom_up; int script_on; char script_name[512]; char format[16]; diff --git a/src/zhttpd.c b/src/zhttpd.c old mode 100644 new mode 100755 index d972ddd..965d8ce --- a/src/zhttpd.c +++ b/src/zhttpd.c @@ -31,6 +31,7 @@ #include "zdb.h" #include "zaccess.h" #include "cjson/cJSON.h" +#include "url.h" typedef struct { evhtp_request_t *req; @@ -141,6 +142,27 @@ int zimg_etag_set(evhtp_request_t *request, char *buff, size_t len) return result; } +/** + * @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; +} /** * @brief conf_get_headers get headers from conf * @@ -488,7 +510,7 @@ int on_chunk_data(multipart_parser* p, const char *at, size_t length) return 0; //multipart_parser_set_data(p, mp_arg); char md5sum[33]; - if(save_img(mp_arg->thr_arg, at, length, md5sum) == -1) + if(save_img(mp_arg->thr_arg, "", at, length, md5sum) == -1) { LOG_PRINT(LOG_DEBUG, "Image Save Failed!"); LOG_PRINT(LOG_ERROR, "%s fail post save", mp_arg->address); @@ -553,10 +575,11 @@ int binary_parse(evhtp_request_t *req, const char *content_type, const char *add goto done; } char md5sum[33]; - LOG_PRINT(LOG_DEBUG, "Begin to Save Image..."); evthr_t *thread = get_request_thr(req); thr_arg_t *thr_arg = (thr_arg_t *)evthr_get_aux(thread); - if(save_img(thr_arg, buff, post_size, md5sum) == -1) + const char *filename = evhtp_header_find(req->headers_in, "zimg-filename"); + LOG_PRINT(LOG_DEBUG, "Begin to Save Image %s...", filename); + if(save_img(thr_arg, filename, buff, post_size, md5sum) == -1) { LOG_PRINT(LOG_DEBUG, "Image Save Failed!"); LOG_PRINT(LOG_ERROR, "%s fail post save", address); @@ -693,12 +716,6 @@ void post_request_cb(evhtp_request_t *req, void *arg) 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); @@ -764,7 +781,12 @@ void post_request_cb(evhtp_request_t *req, void *arg) err_no = 6; goto err; } - evbuf_t *buf; + const char *filename = evhtp_header_find(req->headers_in, "zimg-filename"); + if(!filename) + { + LOG_PRINT(LOG_DEBUG, "Get zimg-filename not found!"); + } + evbuf_t *buf; buf = req->buffer_in; buff = (char *)malloc(post_size); if(buff == NULL) @@ -855,12 +877,6 @@ void get_request_cb(evhtp_request_t *req, void *arg) 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); @@ -1106,7 +1122,28 @@ void get_request_cb(evhtp_request_t *req, void *arg) 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)); + if (proportion == 0) + { + LOG_PRINT(LOG_DEBUG, "Got the File Schema:%s, length:%d", zimg_req->file_schema, strlen(zimg_req->file_schema)); + if( strlen(zimg_req->file_schema)>0 ) + { + cJSON * root = cJSON_Parse(zimg_req->file_schema); + char *file_name = cJSON_GetObjectItem(root,"filename")->valuestring; + LOG_PRINT(LOG_DEBUG, "filename: %s", file_name); + + zimg_attachment_set(req,file_name); + + cJSON_Delete(root); + } + else + { + zimg_attachment_set(req,""); + } + } + else + { + 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) @@ -1155,12 +1192,6 @@ void admin_request_cb(evhtp_request_t *req, void *arg) 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); @@ -1342,12 +1373,6 @@ void info_request_cb(evhtp_request_t *req, void *arg) 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); diff --git a/src/zimg.c b/src/zimg.c old mode 100644 new mode 100755 index 9e13fbc..ce1ed8f --- a/src/zimg.c +++ b/src/zimg.c @@ -36,8 +36,8 @@ #include "zlscale.h" #include "cjson/cJSON.h" -int save_img(thr_arg_t *thr_arg, const char *buff, const int len, char *md5); -int new_img(const char *buff, const size_t len, const char *save_name); +int save_img(thr_arg_t *thr_arg, const char *origin_file_name, const char *buff, const int len, char *md5); +int new_img(const char *buff, const size_t len, const char *save_name, const char *origin_file_name); int get_img(zimg_req_t *req, evhtp_request_t *request); int admin_img(evhtp_request_t *req, thr_arg_t *thr_arg, char *md5, int t); int info_img(evhtp_request_t *request, thr_arg_t *thr_arg, char *md5); @@ -53,7 +53,7 @@ int info_img(evhtp_request_t *request, thr_arg_t *thr_arg, char *md5); * * @return 1 for success and -1 for fail */ -int save_img(thr_arg_t *thr_arg, const char *buff, const int len, char *md5) +int save_img(thr_arg_t *thr_arg, const char *origin_file_name, const char *buff, const int len, char *md5) { int result = -1; @@ -113,26 +113,21 @@ int save_img(thr_arg_t *thr_arg, const char *buff, const int len, char *md5) snprintf(save_path, 512, "%s/%d/%d/%s", settings.img_path, lvl1, lvl2, md5sum); LOG_PRINT(LOG_DEBUG, "save_path: %s", save_path); - if(is_dir(save_path) != 1) - { - if(mk_dirs(save_path) == -1) - { - LOG_PRINT(LOG_DEBUG, "save_path[%s] Create Failed!", save_path); - goto done; - } - LOG_PRINT(LOG_DEBUG, "save_path[%s] Create Finish.", save_path); - } - - snprintf(save_name, 512, "%s/0*0", save_path); - LOG_PRINT(LOG_DEBUG, "save_name-->: %s", save_name); - - if(is_file(save_name) == 1) + if(is_dir(save_path) == 1) { LOG_PRINT(LOG_DEBUG, "Check File Exist. Needn't Save."); goto cache; } - if(new_img(buff, len, save_name) == -1) + if(mk_dirs(save_path) == -1) + { + LOG_PRINT(LOG_DEBUG, "save_path[%s] Create Failed!", save_path); + goto done; + } + LOG_PRINT(LOG_DEBUG, "save_path[%s] Create Finish.", save_path); + snprintf(save_name, 512, "%s/0*0", save_path); + LOG_PRINT(LOG_DEBUG, "save_name-->: %s", save_name); + if(new_img(buff, len, save_name, origin_file_name) == -1) { LOG_PRINT(LOG_DEBUG, "Save Image[%s] Failed!", save_name); goto done; @@ -158,13 +153,30 @@ int save_img(thr_arg_t *thr_arg, const char *buff, const int len, char *md5) * * @return 1 for success and -1 for fail. */ -int new_img(const char *buff, const size_t len, const char *save_name) +int new_img(const char *buff, const size_t len, const char *save_name, const char *origin_file_name) { + char schema_name[640]; int result = -1; LOG_PRINT(LOG_DEBUG, "Start to Storage the New Image..."); int fd = -1; int wlen = 0; + snprintf(schema_name,sizeof(schema_name)-1,"%s_schema",save_name); + LOG_PRINT(LOG_DEBUG, "schema_name is :%s ", schema_name); + + if ( origin_file_name && strlen(origin_file_name) > 0 ) + { + cJSON *j_ret = cJSON_CreateObject(); + cJSON_AddStringToObject(j_ret, "filename", origin_file_name); + char *str_schema = cJSON_PrintUnformatted(j_ret); + LOG_PRINT(LOG_DEBUG, "file schema: %s", str_schema); + FILE *fp = fopen(schema_name,"w"); + fprintf(fp,"%s",str_schema); + fclose(fp); + cJSON_Delete(j_ret); + free(str_schema); + } + if((fd = open(save_name, O_WRONLY | O_TRUNC | O_CREAT, 00644)) < 0) { LOG_PRINT(LOG_DEBUG, "fd(%s) open failed!", save_name); @@ -254,6 +266,16 @@ int get_img(zimg_req_t *req, evhtp_request_t *request) char orig_path[512]; snprintf(orig_path, 512, "%s/0*0", whole_path); LOG_PRINT(LOG_DEBUG, "0rig File Path: %s", orig_path); + char schema_path[512]; + snprintf(schema_path, 512, "%s/0*0_schema", whole_path); + LOG_PRINT(LOG_DEBUG, "Schema File Path: %s", schema_path); + memset(req->file_schema,0,1024); + FILE *fp = fopen(schema_path,"r"); + if ( fp != NULL ) + { + fgets(req->file_schema,1023,fp); + fclose(fp); + } char rsp_path[512]; if(settings.script_on == 1 && req->type != NULL) @@ -403,7 +425,7 @@ int get_img(zimg_req_t *req, evhtp_request_t *request) if(save_new == 1) { LOG_PRINT(LOG_DEBUG, "Image[%s] is Not Existed. Begin to Save it.", rsp_path); - if(new_img(buff, len, rsp_path) == -1) + if(new_img(buff, len, rsp_path, "") == -1) { LOG_PRINT(LOG_DEBUG, "New Image[%s] Save Failed!", rsp_path); LOG_PRINT(LOG_WARNING, "fail save %s", rsp_path); diff --git a/src/zimg.h b/src/zimg.h old mode 100644 new mode 100755 index 73b09f2..8e23b57 --- a/src/zimg.h +++ b/src/zimg.h @@ -23,8 +23,8 @@ #include "zcommon.h" -int save_img(thr_arg_t *thr_arg, const char *buff, const int len, char *md5); -int new_img(const char *buff, const size_t len, const char *save_name); +int save_img(thr_arg_t *thr_arg, const char *origin_file_name, const char *buff, const int len, char *md5); +int new_img(const char *buff, const size_t len, const char *save_name, const char *origin_file_name); int get_img(zimg_req_t *req, evhtp_request_t *request); int admin_img(evhtp_request_t *req, thr_arg_t *thr_arg, char *md5, int t); int info_img(evhtp_request_t *request, thr_arg_t *thr_arg, char *md5);