Fetching contributors…
Cannot retrieve contributors at this time
271 lines (220 sloc) 7.66 KB
* Copyright (C) 2006, 2008 Valery Kholodkov
#include <openssl/md5.h>
#include <md5.h>
#define MD5Init MD5_Init
#define MD5Update MD5_Update
#define MD5Final MD5_Final
#include <openssl/sha.h>
#include <sha.h>
#define MULTIPART_FORM_DATA_STRING "multipart/form-data"
#define BOUNDARY_STRING "boundary="
#define CONTENT_DISPOSITION_STRING "Content-Disposition:"
#define CONTENT_TYPE_STRING "Content-Type:"
#define FORM_DATA_STRING "form-data"
#define ATTACHMENT_STRING "attachment"
#define FILENAME_STRING "filename=\""
#define FIELDNAME_STRING "name=\""
#define NGX_UPLOAD_SUBMODULE 0x444c5055 // UPLD
* State of multipart/form-data parser
typedef enum {
} upload_state_t;
* Template for a field to generate in output form
typedef struct {
ngx_table_elt_t value;
ngx_array_t *field_lengths;
ngx_array_t *field_values;
ngx_array_t *value_lengths;
ngx_array_t *value_values;
} ngx_http_upload_field_template_t;
* Filter for fields in output form
typedef struct {
#if (NGX_PCRE)
ngx_regex_t *regex;
ngx_int_t ncaptures;
ngx_str_t text;
} ngx_http_upload_field_filter_t;
struct ngx_http_upload_ctx_s;
* Filter for content of certain type
typedef struct {
ngx_int_t (*start)(struct ngx_http_upload_ctx_s *upload_ctx);
void (*finish)(struct ngx_http_upload_ctx_s *upload_ctx);
void (*abort)(struct ngx_http_upload_ctx_s *upload_ctx);
ngx_int_t (*process_chain)(struct ngx_http_upload_ctx_s *upload_ctx, ngx_chain_t *chain);
} ngx_upload_content_filter_t;
typedef ngx_upload_content_filter_t ngx_upload_field_filter_t;
* Mapping of a content type to slave location config
struct ngx_http_upload_loc_conf_s;
typedef struct {
ngx_str_t content_type;
ngx_http_core_loc_conf_t *conf;
} ngx_upload_content_type_map_t;
* Upload cleanup record
typedef struct ngx_http_upload_cleanup_s {
ngx_fd_t fd;
u_char *filename;
ngx_http_headers_out_t *headers_out;
ngx_array_t *cleanup_statuses;
ngx_log_t *log;
unsigned int aborted:1;
} ngx_upload_cleanup_t;
* Upload configuration for specific location
typedef struct ngx_http_upload_loc_conf_s {
struct ngx_http_upload_loc_conf_s *parent;
ngx_str_t url;
ngx_path_t *store_path;
ngx_uint_t store_access;
size_t buffer_size;
size_t max_header_len;
size_t max_output_body_len;
off_t max_file_size;
ngx_array_t *field_templates;
ngx_array_t *aggregate_field_templates;
ngx_array_t *field_filters;
ngx_array_t *cleanup_statuses;
ngx_flag_t forward_args;
ngx_array_t *content_filters;
ngx_array_t *content_type_map;
ngx_array_t *void_content_types;
ngx_str_t archive_elm_separator;
ngx_str_t archive_path_separator;
unsigned int md5:1;
unsigned int sha1:1;
unsigned int crc32:1;
} ngx_http_upload_loc_conf_t;
typedef struct ngx_http_upload_md5_ctx_s {
MD5_CTX md5;
u_char md5_digest[MD5_DIGEST_LENGTH * 2];
} ngx_http_upload_md5_ctx_t;
typedef struct ngx_http_upload_sha1_ctx_s {
SHA_CTX sha1;
u_char sha1_digest[SHA_DIGEST_LENGTH * 2];
} ngx_http_upload_sha1_ctx_t;
* Upload module context
typedef struct ngx_http_upload_ctx_s {
ngx_str_t boundary;
u_char *boundary_start;
u_char *boundary_pos;
upload_state_t state;
u_char *header_accumulator;
u_char *header_accumulator_end;
u_char *header_accumulator_pos;
ngx_str_t field_name;
ngx_str_t file_name;
ngx_str_t content_type;
ngx_str_t archive_elm;
ngx_str_t archive_path;
ngx_buf_t *output_buffer;
ngx_int_t (*start_part_f)(struct ngx_http_upload_ctx_s *upload_ctx);
void (*finish_part_f)(struct ngx_http_upload_ctx_s *upload_ctx);
void (*abort_part_f)(struct ngx_http_upload_ctx_s *upload_ctx);
ngx_int_t (*process_chain_f)(struct ngx_http_upload_ctx_s *upload_ctx, ngx_chain_t *chain);
ngx_http_request_t *request;
ngx_log_t *log;
void **original_loc_conf;
ngx_file_t output_file;
ngx_chain_t *chain;
ngx_chain_t *last;
ngx_chain_t *checkpoint;
size_t output_body_len;
ngx_pool_cleanup_t *cln;
ngx_http_upload_md5_ctx_t *md5_ctx;
ngx_http_upload_sha1_ctx_t *sha1_ctx;
uint32_t crc32;
ngx_array_t *current_content_filter_chain;
ngx_uint_t current_content_filter_idx;
unsigned int first_part:1;
unsigned int discard_data:1;
unsigned int is_file:1;
unsigned int calculate_crc32:1;
} ngx_http_upload_ctx_t;
ngx_module_t ngx_http_upload_module;
ngx_int_t ngx_upload_set_exten(ngx_http_upload_ctx_t *u, ngx_str_t *file_name, ngx_str_t *exten);
ngx_int_t ngx_upload_resolve_content_type(ngx_http_upload_ctx_t *u, ngx_str_t *exten, ngx_str_t *content_type);
#define ngx_upload_set_file_name(ctx, fn) \
do{ \
(ctx)-> = (fn)->data; \
(ctx)->file_name.len = (fn)->len; \
}while(0); \
#define ngx_upload_get_file_name(ctx, fn) \
do{ \
(fn)->data = (ctx)->; \
(fn)->len = (ctx)->file_name.len; \
}while(0); \
#define ngx_upload_set_content_type(ctx, ct) \
do{ \
(ctx)-> = (ct)->data; \
(ctx)->content_type.len = (ct)->len; \
}while(0); \
#define ngx_upload_get_content_type(ctx, ct) \
do{ \
(ct)->data = (ctx)->; \
(ct)->len = (ctx)->content_type.len; \
}while(0); \
#define ngx_upload_set_archive_elm(ctx, ae) \
do{ \
(ctx)-> = (ae)->data; \
(ctx)->archive_elm.len = (ae)->len; \
}while(0); \
#define ngx_upload_get_archive_elm(ctx, ae) \
do{ \
(ae)->data = (ctx)->; \
(ae)->len = (ctx)->archive_elm.len; \
}while(0); \
#define ngx_upload_set_archive_path(ctx, ap) \
do{ \
(ctx)-> = (ap)->data; \
(ctx)->archive_path.len = (ap)->len; \
}while(0); \
#define ngx_upload_get_archive_path(ctx, ap) \
do{ \
(ap)->data = (ctx)->; \
(ap)->len = (ctx)->archive_path.len; \
}while(0); \
ngx_upload_get_next_field_filter(ngx_http_upload_ctx_t *ctx);
ngx_upload_get_next_content_filter(ngx_http_upload_ctx_t *ctx);
ngx_http_upload_add_filter(ngx_http_upload_loc_conf_t *ulcf,
ngx_upload_content_filter_t *cflt, ngx_pool_t *pool);