Index: ngx_http_upload_module.c
===================================================================
--- ngx_http_upload_module.c	(revision 62)
+++ ngx_http_upload_module.c	(working copy)
@@ -33,6 +33,8 @@
 #define ATTACHMENT_STRING                       "attachment"
 #define FILENAME_STRING                         "filename=\""
 #define FIELDNAME_STRING                        "name=\""
+#define UNDEFINED_CONTENT_TYPE1                 "application/octet-stream"
+#define UNDEFINED_CONTENT_TYPE2                 "application/oct-stream"
 
 #define NGX_UPLOAD_MALFORMED    -1
 #define NGX_UPLOAD_NOMEM        -2
@@ -2088,7 +2090,113 @@
     upload_ctx->content_type.data = NULL;
 } /* }}} */
 
+static ngx_int_t /* {{{ ngx_upload_set_exten */
+ngx_upload_set_exten(ngx_http_upload_ctx_t *u, ngx_str_t *exten)
+{
+    ngx_int_t  i;
+
+    exten->len = 0;
+    exten->data = NULL;
+
+    for (i = u->file_name.len - 1; i > 1; i--) {
+        if (u->file_name.data[i] == '.' && u->file_name.data[i - 1] != '/') {
+
+            exten->len = u->file_name.len - i - 1;
+            exten->data = &u->file_name.data[i + 1];
+
+            break;
+
+        } else if (u->file_name.data[i] == '/') {
+            break;
+        }
+    }
+
+    return NGX_OK;
+} /* }}} */
+
+static ngx_int_t /* {{{ ngx_upload_resolve_content_type */
+ngx_upload_resolve_content_type(ngx_http_upload_ctx_t *u, ngx_str_t *exten, ngx_str_t *content_type)
+{
+    u_char                     c, *p, *_exten;
+    ngx_str_t                 *type;
+    ngx_uint_t                 i, hash;
+    ngx_http_core_loc_conf_t  *clcf;
+
+    clcf = ngx_http_get_module_loc_conf(u->request, ngx_http_core_module);
+
+    if (exten->len) {
+
+        hash = 0;
+
+        for (i = 0; i < exten->len; i++) {
+            c = exten->data[i];
+
+            if (c >= 'A' && c <= 'Z') {
+
+                p = ngx_palloc(u->request->pool, exten->len);
+                if (p == NULL) {
+                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
+                }
+
+                hash = 0;
+                _exten = p;
+
+                for (i = 0; i < exten->len; i++) {
+                    c = ngx_tolower(exten->data[i]);
+                    hash = ngx_hash(hash, c);
+                    *p++ = c;
+                }
+
+                exten->data = _exten;
+
+                break;
+            }
+
+            hash = ngx_hash(hash, c);
+        }
+
+        type = ngx_hash_find(&clcf->types_hash, hash,
+                             exten->data, exten->len);
+
+        if (type) {
+            *content_type = *type;
+
+            return NGX_OK;
+        }
+    }
+
+    content_type->len = sizeof("application/octet-stream") - 1;
+    content_type->data = (u_char*)"application/octet-stream";
+
+    return NGX_OK;
+} /* }}} */
+
 static ngx_int_t upload_start_file(ngx_http_upload_ctx_t *upload_ctx) { /* {{{ */
+    ngx_str_t                 exten, content_type;
+
+    upload_ctx->start_part_f = ngx_http_upload_start_handler;
+    upload_ctx->finish_part_f = ngx_http_upload_finish_handler;
+    upload_ctx->abort_part_f = ngx_http_upload_abort_handler;
+    upload_ctx->flush_output_buffer_f = ngx_http_upload_flush_output_buffer;
+
+    if(upload_ctx->is_file) {
+        if(upload_ctx->content_type.len == 0 ||
+            !ngx_strncasecmp(upload_ctx->content_type.data, (u_char*) UNDEFINED_CONTENT_TYPE1, sizeof(UNDEFINED_CONTENT_TYPE1) - 1) || 
+            !ngx_strncasecmp(upload_ctx->content_type.data, (u_char*) UNDEFINED_CONTENT_TYPE2, sizeof(UNDEFINED_CONTENT_TYPE2) - 1)) {
+            ngx_upload_set_exten(upload_ctx, &exten);
+
+            ngx_upload_resolve_content_type(upload_ctx, &exten, &content_type);
+
+            ngx_log_debug2(NGX_LOG_INFO, upload_ctx->log, 0
+                , "guessed content type by extension \"%V\" -> \"%V\""
+                , &exten
+                , &content_type
+                );
+
+            upload_ctx->content_type = content_type;
+        }
+    }
+
     // Call user-defined event handler
     if(upload_ctx->start_part_f)
         return upload_ctx->start_part_f(upload_ctx);