在做CDN的项目中, 由于媒体文件没有后缀, NGINX不会自动根据mime.types来自动获取Content-Type的值,之前使用默认的Content-Type: application/octet-stream; 有部分客户端不会自己去识别流的格式, 不指定正确的Content-Type值无法播放文件,所以我只有修改NGINX源码来指定要发送的Content-Type值了。
记录下我修改的东西,方便以后查阅。
ngx_int_t ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status, ngx_str_t *ct, ngx_http_complex_value_t *cv) ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r) r->uri 得到文件名, 查找 文件名.type //GDB调试时得到的调用堆栈 Breakpoint 1, ngx_http_set_content_type (r=0x7e6760) at src/http/ngx_http_core_module.c:1750 1750 if (r->headers_out.content_type.len) { (gdb) bt #0 ngx_http_set_content_type (r=0x7e6760) at src/http/ngx_http_core_module.c:1750 #1 0x0000000000482704 in ngx_http_static_handler (r=0x7e6760) at src/http/modules/ngx_http_static_module.c:223 #2 0x00000000004546f1 in ngx_http_core_content_phase (r=0x7e6760, ph=0x80a3e8) at src/http/ngx_http_core_module.c:1414 #3 0x00000000004531d7 in ngx_http_core_run_phases (r=0x7e6760) at src/http/ngx_http_core_module.c:888 #4 0x000000000045314e in ngx_http_handler (r=0x7e6760) at src/http/ngx_http_core_module.c:871 #5 0x0000000000461604 in ngx_http_process_request (r=0x7e6760) at src/http/ngx_http_request.c:1694 #6 0x000000000046000f in ngx_http_process_request_headers (rev=0x80cef8) at src/http/ngx_http_request.c:1144 #7 0x000000000045f7c4 in ngx_http_process_request_line (rev=0x80cef8) at src/http/ngx_http_request.c:940 #8 0x000000000045e9ac in ngx_http_init_request (rev=0x80cef8) at src/http/ngx_http_request.c:524 #9 0x0000000000448d2a in ngx_epoll_process_events (cycle=0x7a1760, timer=60000, flags=1) at src/event/modules/ngx_epoll_module.c:683 #10 0x0000000000439738 in ngx_process_events_and_timers (cycle=0x7a1760) at src/event/ngx_event.c:247 #11 0x0000000000445916 in ngx_single_process_cycle (cycle=0x7a1760) at src/os/unix/ngx_process_cycle.c:316 #12 0x00000000004153e8 in main (argc=1, argv=0x7fffffffe548) at src/core/nginx.c:407 //修改下面这个函数即可 ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r) { u_char c, *exten; ngx_str_t *type; ngx_uint_t i, hash; ngx_http_core_loc_conf_t *clcf; if (r->headers_out.content_type.len) { return NGX_OK; } clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (r->exten.len) { hash = 0; for (i = 0; i < r->exten.len; i++) { c = r->exten.data[i]; if (c >= 'A' && c <= 'Z') { exten = ngx_pnalloc(r->pool, r->exten.len); if (exten == NULL) { return NGX_ERROR; } hash = ngx_hash_strlow(exten, r->exten.data, r->exten.len); r->exten.data = exten; break; } hash = ngx_hash(hash, c); } type = ngx_hash_find(&clcf->types_hash, hash, r->exten.data, r->exten.len); if (type) { r->headers_out.content_type_len = type->len; r->headers_out.content_type = *type; return NGX_OK; } } //性能影响就影响吧,只是为了做个功能测试,把Content-Type的值记录到一个文本文件里面,暂时没想到啥好的办法 /////////////////////处理Content-Type添加的代码//////////////////////////////////// char url[1024]={0}; strncpy (url, r->uri.data, r->uri.len); strcat (url, ".type"); char filename[256]={0}; snprintf (filename, sizeof(filename)-1, "../html%s", url); char stype[64]={0}; FILE* fp = fopen (filename, "rb"); if (fp != NULL) { fread (stype, sizeof(char), sizeof(stype), fp); fclose(fp); int slen = strlen(stype); char* sp = stype+slen; while (sp != stype) { sp--; if (*sp == '\r' || *sp == '\n' || *sp == ' ') *sp = '\0'; } ngx_str_t cnttype; cnttype.len = strlen(stype); cnttype.data = strdup(stype); r->headers_out.content_type_len = cnttype.len; r->headers_out.content_type = cnttype; return NGX_OK; } ///////////////////////////////////////////////////////////////////// r->headers_out.content_type_len = clcf->default_type.len; r->headers_out.content_type = clcf->default_type; return NGX_OK; }