static ngx_int_t ngx_rtmp_dash_write_playlist(ngx_rtmp_session_t *s) { char *sep; u_char *p, *last; ssize_t n; ngx_fd_t fd; struct tm tm; ngx_str_t noname, *name; ngx_uint_t i, frame_rate_num, frame_rate_denom; ngx_rtmp_dash_ctx_t *ctx; ngx_rtmp_codec_ctx_t *codec_ctx; ngx_rtmp_dash_frag_t *f; ngx_rtmp_dash_app_conf_t *dacf; static u_char buffer[NGX_RTMP_DASH_BUFSIZE]; static u_char start_time[sizeof("1970-09-28T12:00:00+06:00")]; static u_char end_time[sizeof("1970-09-28T12:00:00+06:00")]; static u_char frame_rate[(NGX_INT_T_LEN * 2) + 2]; dacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_dash_module); ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_dash_module); codec_ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module); if (dacf == NULL || ctx == NULL || codec_ctx == NULL) { return NGX_ERROR; } if (ctx->id == 0) { ngx_rtmp_dash_write_init_segments(s); } fd = ngx_open_file(ctx->playlist_bak.data, NGX_FILE_WRONLY, NGX_FILE_TRUNCATE, NGX_FILE_DEFAULT_ACCESS); if (fd == NGX_INVALID_FILE) { ngx_log_error(NGX_LOG_ERR, s->connection->log, ngx_errno, "dash: open failed: '%V'", &ctx->playlist_bak); return NGX_ERROR; } #define NGX_RTMP_DASH_MANIFEST_HEADER \ "<?xml version=\"1.0\"?>\n" \ "<MPD\n" \ " type=\"dynamic\"\n" \ " xmlns=\"urn:mpeg:dash:schema:mpd:2011\"\n" \ " availabilityStartTime=\"%s\"\n" \ " availabilityEndTime=\"%s\"\n" \ " minimumUpdatePeriod=\"PT%uiS\"\n" \ " minBufferTime=\"PT%uiS\"\n" \ " timeShiftBufferDepth=\"PT0H0M0.00S\"\n" \ " suggestedPresentationDelay=\"PT%uiS\"\n" \ " profiles=\"urn:hbbtv:dash:profile:isoff-live:2012," \ "urn:mpeg:dash:profile:isoff-live:2011\"\n" \ " xmlns:xsi=\"http://www.w3.org/2011/XMLSchema-instance\"\n" \ " xsi:schemaLocation=\"urn:mpeg:DASH:schema:MPD:2011 DASH-MPD.xsd\">\n" \ " <Period start=\"PT0S\" id=\"dash\">\n" #define NGX_RTMP_DASH_MANIFEST_VIDEO \ " <AdaptationSet\n" \ " id=\"1\"\n" \ " segmentAlignment=\"true\"\n" \ " maxWidth=\"%ui\"\n" \ " maxHeight=\"%ui\"\n" \ " maxFrameRate=\"%s\">\n" \ " <Representation\n" \ " id=\"%V_H264\"\n" \ " mimeType=\"video/mp4\"\n" \ " codecs=\"avc1.%02uxi%02uxi%02uxi\"\n" \ " width=\"%ui\"\n" \ " height=\"%ui\"\n" \ " frameRate=\"%s\"\n" \ " sar=\"1:1\"\n" \ " startWithSAP=\"1\"\n" \ " bandwidth=\"%ui\">\n" \ " <SegmentTemplate\n" \ " presentationTimeOffset=\"0\"\n" \ " timescale=\"1000\"\n" \ " media=\"%V%s$Time$.m4v\"\n" \ " initialization=\"%V%sinit.m4v\">\n" \ " <SegmentTimeline>\n" #define NGX_RTMP_DASH_MANIFEST_VIDEO_FOOTER \ " </SegmentTimeline>\n" \ " </SegmentTemplate>\n" \ " </Representation>\n" \ " </AdaptationSet>\n" #define NGX_RTMP_DASH_MANIFEST_TIME \ " <S t=\"%uD\" d=\"%uD\"/>\n" #define NGX_RTMP_DASH_MANIFEST_AUDIO \ " <AdaptationSet\n" \ " id=\"2\"\n" \ " segmentAlignment=\"true\">\n" \ " <AudioChannelConfiguration\n" \ " schemeIdUri=\"urn:mpeg:dash:" \ "23003:3:audio_channel_configuration:2011\"\n" \ " value=\"1\"/>\n" \ " <Representation\n" \ " id=\"%V_AAC\"\n" \ " mimeType=\"audio/mp4\"\n" \ " codecs=\"mp4a.%s\"\n" \ " audioSamplingRate=\"%ui\"\n" \ " startWithSAP=\"1\"\n" \ " bandwidth=\"%ui\">\n" \ " <SegmentTemplate\n" \ " presentationTimeOffset=\"0\"\n" \ " timescale=\"1000\"\n" \ " media=\"%V%s$Time$.m4a\"\n" \ " initialization=\"%V%sinit.m4a\">\n" \ " <SegmentTimeline>\n" #define NGX_RTMP_DASH_MANIFEST_AUDIO_FOOTER \ " </SegmentTimeline>\n" \ " </SegmentTemplate>\n" \ " </Representation>\n" \ " </AdaptationSet>\n" #define NGX_RTMP_DASH_MANIFEST_FOOTER \ " </Period>\n" \ "</MPD>\n" ngx_libc_localtime(ctx->start_time.sec + ngx_rtmp_dash_get_frag(s, 0)->timestamp / 1000, &tm); *ngx_sprintf(start_time, "%4d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, ctx->start_time.gmtoff < 0 ? '-' : '+', ngx_abs(ctx->start_time.gmtoff / 60), ngx_abs(ctx->start_time.gmtoff % 60)) = 0; ngx_libc_localtime(ctx->start_time.sec + (ngx_rtmp_dash_get_frag(s, ctx->nfrags - 1)->timestamp + ngx_rtmp_dash_get_frag(s, ctx->nfrags - 1)->duration) / 1000, &tm); *ngx_sprintf(end_time, "%4d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, ctx->start_time.gmtoff < 0 ? '-' : '+', ngx_abs(ctx->start_time.gmtoff / 60), ngx_abs(ctx->start_time.gmtoff % 60)) = 0; last = buffer + sizeof(buffer); p = ngx_slprintf(buffer, last, NGX_RTMP_DASH_MANIFEST_HEADER, start_time, end_time, (ngx_uint_t) (dacf->fraglen / 1000), (ngx_uint_t) (dacf->fraglen / 1000), (ngx_uint_t) (dacf->fraglen / 500)); n = ngx_write_fd(fd, buffer, p - buffer); ngx_str_null(&noname); name = (dacf->nested ? &noname : &ctx->name); sep = (dacf->nested ? "" : "-"); if (ctx->has_video) { frame_rate_num = (ngx_uint_t) (codec_ctx->frame_rate * 1000.); if (frame_rate_num % 1000 == 0) { *ngx_sprintf(frame_rate, "%ui", frame_rate_num / 1000) = 0; } else { frame_rate_denom = 1000; switch (frame_rate_num) { case 23976: frame_rate_num = 24000; frame_rate_denom = 1001; break; case 29970: frame_rate_num = 30000; frame_rate_denom = 1001; break; case 59940: frame_rate_num = 60000; frame_rate_denom = 1001; break; } *ngx_sprintf(frame_rate, "%ui/%ui", frame_rate_num, frame_rate_denom) = 0; } p = ngx_slprintf(buffer, last, NGX_RTMP_DASH_MANIFEST_VIDEO, codec_ctx->width, codec_ctx->height, frame_rate, &ctx->name, codec_ctx->avc_profile, codec_ctx->avc_compat, codec_ctx->avc_level, codec_ctx->width, codec_ctx->height, frame_rate, (ngx_uint_t) (codec_ctx->video_data_rate * 1000), name, sep, name, sep); for (i = 0; i < ctx->nfrags; i++) { f = ngx_rtmp_dash_get_frag(s, i); p = ngx_slprintf(p, last, NGX_RTMP_DASH_MANIFEST_TIME, f->timestamp, f->duration); } p = ngx_slprintf(p, last, NGX_RTMP_DASH_MANIFEST_VIDEO_FOOTER); n = ngx_write_fd(fd, buffer, p - buffer); } if (ctx->has_audio) { p = ngx_slprintf(buffer, last, NGX_RTMP_DASH_MANIFEST_AUDIO, &ctx->name, codec_ctx->audio_codec_id == NGX_RTMP_AUDIO_AAC ? (codec_ctx->aac_sbr ? "40.5" : "40.2") : "6b", codec_ctx->sample_rate, (ngx_uint_t) (codec_ctx->audio_data_rate * 1000), name, sep, name, sep); for (i = 0; i < ctx->nfrags; i++) { f = ngx_rtmp_dash_get_frag(s, i); p = ngx_slprintf(p, last, NGX_RTMP_DASH_MANIFEST_TIME, f->timestamp, f->duration); } p = ngx_slprintf(p, last, NGX_RTMP_DASH_MANIFEST_AUDIO_FOOTER); n = ngx_write_fd(fd, buffer, p - buffer); } p = ngx_slprintf(buffer, last, NGX_RTMP_DASH_MANIFEST_FOOTER); n = ngx_write_fd(fd, buffer, p - buffer); if (n < 0) { ngx_log_error(NGX_LOG_ERR, s->connection->log, ngx_errno, "dash: write failed: '%V'", &ctx->playlist_bak); ngx_close_file(fd); return NGX_ERROR; } ngx_close_file(fd); if (ngx_rtmp_dash_rename_file(ctx->playlist_bak.data, ctx->playlist.data) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ERR, s->connection->log, ngx_errno, "dash: rename failed: '%V'->'%V'", &ctx->playlist_bak, &ctx->playlist); return NGX_ERROR; } return NGX_OK; }
void ngx_log_error_coreall(ngx_uint_t level, ngx_log_t *log, const char* filename, int lineno, ngx_err_t err, const char *fmt, va_list args) #endif { #if (NGX_HAVE_VARIADIC_MACROS) va_list args; #endif u_char *p, *last, *msg; ssize_t n; ngx_uint_t wrote_stderr, debug_connection; u_char errstr[NGX_MAX_ERROR_STR]; char filebuf[52]; last = errstr + NGX_MAX_ERROR_STR; p = ngx_cpymem(errstr, ngx_cached_err_log_time.data, ngx_cached_err_log_time.len); snprintf(filebuf, sizeof(filebuf), "[%35s, %5d][yangyazhou @@@ test]", filename, lineno); p = ngx_slprintf(p, last, "%s ", filebuf); p = ngx_slprintf(p, last, " [%V] ", &err_levels[level]); /* pid#tid */ p = ngx_slprintf(p, last, "%P#" NGX_TID_T_FMT ": ", ngx_log_pid, ngx_log_tid); //进程ID和线程ID(在开启线程池的时候线程ID和进程ID不同) if (log->connection) { p = ngx_slprintf(p, last, "*%uA ", log->connection); } msg = p; #if (NGX_HAVE_VARIADIC_MACROS) va_start(args, fmt); p = ngx_vslprintf(p, last, fmt, args); va_end(args); #else p = ngx_vslprintf(p, last, fmt, args); #endif if (err) { p = ngx_log_errno(p, last, err); } if (level != NGX_LOG_DEBUG && log->handler) { p = log->handler(log, p, last - p); } if (p > last - NGX_LINEFEED_SIZE) { p = last - NGX_LINEFEED_SIZE; } ngx_linefeed(p); wrote_stderr = 0; debug_connection = (log->log_level & NGX_LOG_DEBUG_CONNECTION) != 0; while (log) { if (log->writer) { log->writer(log, level, errstr, p - errstr); goto next; } if (ngx_time() == log->disk_full_time) { /* * on FreeBSD writing to a full filesystem with enabled softupdates * may block process for much longer time than writing to non-full * filesystem, so we skip writing to a log for one second */ goto next; } n = ngx_write_fd(log->file->fd, errstr, p - errstr); //写到log文件中 if (n == -1 && ngx_errno == NGX_ENOSPC) { log->disk_full_time = ngx_time(); } if (log->file->fd == ngx_stderr) { wrote_stderr = 1; } next: log = log->next; } if (!ngx_use_stderr || level > NGX_LOG_WARN || wrote_stderr) /* 如果满足这些条件,则不会输出打印到前台,只会写到errlog文件中 */ { return; } msg -= (7 + err_levels[level].len + 3); (void) ngx_sprintf(msg, "nginx: [%V] ", &err_levels[level]); (void) ngx_write_console(ngx_stderr, msg, p - msg); }
char * ngx_log_set_log(ngx_conf_t *cf, ngx_log_t **head) { ngx_log_t *new_log; ngx_str_t *value, name; ngx_syslog_peer_t *peer; if (*head != NULL && (*head)->log_level == 0) { new_log = *head; } else { new_log = ngx_pcalloc(cf->pool, sizeof(ngx_log_t)); if (new_log == NULL) { return NGX_CONF_ERROR; } if (*head == NULL) { *head = new_log; } } value = cf->args->elts; if (ngx_strcmp(value[1].data, "stderr") == 0) { ngx_str_null(&name); cf->cycle->log_use_stderr = 1; new_log->file = ngx_conf_open_file(cf->cycle, &name); if (new_log->file == NULL) { return NGX_CONF_ERROR; } } else if (ngx_strncmp(value[1].data, "memory:", 7) == 0) { #if (NGX_DEBUG) size_t size, needed; ngx_pool_cleanup_t *cln; ngx_log_memory_buf_t *buf; value[1].len -= 7; value[1].data += 7; needed = sizeof("MEMLOG :" NGX_LINEFEED) + cf->conf_file->file.name.len + NGX_SIZE_T_LEN + NGX_INT_T_LEN + NGX_MAX_ERROR_STR; size = ngx_parse_size(&value[1]); if (size == (size_t) NGX_ERROR || size < needed) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid buffer size \"%V\"", &value[1]); return NGX_CONF_ERROR; } buf = ngx_pcalloc(cf->pool, sizeof(ngx_log_memory_buf_t)); if (buf == NULL) { return NGX_CONF_ERROR; } buf->start = ngx_pnalloc(cf->pool, size); if (buf->start == NULL) { return NGX_CONF_ERROR; } buf->end = buf->start + size; buf->pos = ngx_slprintf(buf->start, buf->end, "MEMLOG %uz %V:%ui%N", size, &cf->conf_file->file.name, cf->conf_file->line); ngx_memset(buf->pos, ' ', buf->end - buf->pos); cln = ngx_pool_cleanup_add(cf->pool, 0); if (cln == NULL) { return NGX_CONF_ERROR; } cln->data = new_log; cln->handler = ngx_log_memory_cleanup; new_log->writer = ngx_log_memory_writer; new_log->wdata = buf; #else ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "nginx was built without debug support"); return NGX_CONF_ERROR; #endif } else if (ngx_strncmp(value[1].data, "syslog:", 7) == 0) { peer = ngx_pcalloc(cf->pool, sizeof(ngx_syslog_peer_t)); if (peer == NULL) { return NGX_CONF_ERROR; } if (ngx_syslog_process_conf(cf, peer) != NGX_CONF_OK) { return NGX_CONF_ERROR; } new_log->writer = ngx_syslog_writer; new_log->wdata = peer; } else { new_log->file = ngx_conf_open_file(cf->cycle, &value[1]); if (new_log->file == NULL) { return NGX_CONF_ERROR; } } if (ngx_log_set_levels(cf, new_log) != NGX_CONF_OK) { return NGX_CONF_ERROR; } if (*head != new_log) { ngx_log_insert(*head, new_log); } return NGX_CONF_OK; }
static ngx_int_t ngx_http_reqstat_show_handler(ngx_http_request_t *r) { ngx_int_t rc, *user, index; ngx_buf_t *b; ngx_uint_t i, j; ngx_array_t *display; ngx_chain_t *tl, out, **cl; ngx_queue_t *q; ngx_shm_zone_t **shm_zone; ngx_http_reqstat_ctx_t *ctx; ngx_http_reqstat_conf_t *rlcf; ngx_http_reqstat_conf_t *smcf; ngx_http_reqstat_rbnode_t *node; rlcf = ngx_http_get_module_loc_conf(r, ngx_http_reqstat_module); smcf = ngx_http_get_module_main_conf(r, ngx_http_reqstat_module); display = rlcf->display == NULL ? smcf->monitor : rlcf->display; if (display == NULL) { r->headers_out.status = NGX_HTTP_NO_CONTENT; return ngx_http_send_header(r); } r->headers_out.status = NGX_HTTP_OK; ngx_http_clear_content_length(r); rc = ngx_http_send_header(r); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { return rc; } shm_zone = display->elts; cl = &out.next; for (i = 0; i < display->nelts; i++) { ctx = shm_zone[i]->data; for (q = ngx_queue_head(&ctx->sh->queue); q != ngx_queue_sentinel(&ctx->sh->queue); q = ngx_queue_next(q)) { node = ngx_queue_data(q, ngx_http_reqstat_rbnode_t, queue); if (node->conn_total == 0) { continue; } tl = ngx_alloc_chain_link(r->pool); if (tl == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } b = ngx_calloc_buf(r->pool); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } tl->buf = b; b->start = ngx_pcalloc(r->pool, 512); if (b->start == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } b->end = b->start + 512; b->last = b->pos = b->start; b->temporary = 1; b->last = ngx_slprintf(b->last, b->end, "%*s,", (size_t) node->len, node->data); if (rlcf->user_select) { user = rlcf->user_select->elts; for (j = 0; j < rlcf->user_select->nelts; j++) { if (user[j] < NGX_HTTP_REQSTAT_RSRV) { index = user[j]; b->last = ngx_slprintf(b->last, b->end, "%uA,", *NGX_HTTP_REQSTAT_REQ_FIELD(node, ngx_http_reqstat_fields[index])); } else { index = user[j] - NGX_HTTP_REQSTAT_RSRV; b->last = ngx_slprintf(b->last, b->end, "%uA,", *NGX_HTTP_REQSTAT_REQ_FIELD(node, NGX_HTTP_REQSTAT_EXTRA(index))); } } } else { for (j = 0; j < NGX_HTTP_REQSTAT_RSRV; j++) { b->last = ngx_slprintf(b->last, b->end, "%uA,", *NGX_HTTP_REQSTAT_REQ_FIELD(node, ngx_http_reqstat_fields[j])); } if (ctx->user_defined) { for (j = 0; j < ctx->user_defined->nelts; j++) { b->last = ngx_slprintf(b->last, b->end, "%uA,", *NGX_HTTP_REQSTAT_REQ_FIELD(node, NGX_HTTP_REQSTAT_EXTRA(j))); } } } *(b->last - 1) = '\n'; tl->next = NULL; *cl = tl; cl = &tl->next; } } tl = ngx_alloc_chain_link(r->pool); if (tl == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } tl->buf = ngx_calloc_buf(r->pool); if (tl->buf == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } tl->buf->last_buf = 1; tl->next = NULL; *cl = tl; return ngx_http_output_filter(r, out.next); }
static void ngx_http_groonga_logger_log(grn_ctx *ctx, grn_log_level level, const char *timestamp, const char *title, const char *message, const char *location, void *user_data) { ngx_open_file_t *file = user_data; const char level_marks[] = " EACewnid-"; u_char buffer[NGX_MAX_ERROR_STR]; u_char *last; size_t prefix_size; size_t message_size; size_t location_size; size_t postfix_size; size_t log_message_size; if (!file) { return; } #define LOG_PREFIX_FORMAT "%s|%c|%s" prefix_size = strlen(timestamp) + 1 /* | */ + 1 /* %c */ + 1 /* | */ + strlen(title) + 1 /* a space */; message_size = strlen(message); if (location && *location) { location_size = 1 /* a space */ + strlen(location); } else { location_size = 0; } postfix_size = 1 /* \n */; log_message_size = prefix_size + message_size + location_size + postfix_size; if (log_message_size > NGX_MAX_ERROR_STR) { last = ngx_slprintf(buffer, buffer + NGX_MAX_ERROR_STR, LOG_PREFIX_FORMAT, timestamp, *(level_marks + level), title); ngx_write_fd(file->fd, buffer, last - buffer); ngx_http_groonga_write_fd(file->fd, buffer, NGX_MAX_ERROR_STR, message, message_size); if (location_size > 0) { ngx_write_fd(file->fd, " ", 1); ngx_http_groonga_write_fd(file->fd, buffer, NGX_MAX_ERROR_STR, location, location_size); } ngx_write_fd(file->fd, "\n", 1); } else { if (location && *location) { last = ngx_slprintf(buffer, buffer + NGX_MAX_ERROR_STR, LOG_PREFIX_FORMAT " %s %s\n", timestamp, *(level_marks + level), title, message, location); } else { last = ngx_slprintf(buffer, buffer + NGX_MAX_ERROR_STR, LOG_PREFIX_FORMAT " %s\n", timestamp, *(level_marks + level), title, message); } ngx_write_fd(file->fd, buffer, last - buffer); } #undef LOG_PREFIX_FORMAT }
static ngx_int_t ngx_lua_smtp_handle_response(ngx_lua_smtp_ctx_t *ctx) { u_char *p, *last; ngx_str_t dst, src, *to; ngx_buf_t *b; ngx_uint_t i; enum { sw_start = 0, sw_helo, sw_login, sw_user, sw_passwd, sw_from, sw_to, sw_data, sw_quit, sw_done } state; ngx_log_debug0(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, "lua smtp handle response"); b = ctx->response; if (b->last - b->pos < 4) { return NGX_AGAIN; } if (*(b->last - 2) != CR || *(b->last - 1) != LF) { if (b->last == b->end) { *(b->last - 1) = '\0'; ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "stmp server sent too long response line: \"%s\"", b->pos); return NGX_ERROR; } return NGX_AGAIN; } p = b->pos; last = b->last; b = ctx->request; b->pos = b->start; state = ctx->state; switch (state) { case sw_start: if (p[0] != '2' || p[1] != '2' || p[2] != '0') { return NGX_ERROR; } b->last = ngx_slprintf(b->pos, b->end, "HELO %V" CRLF, &ctx->u.host); state = sw_helo; break; case sw_helo: if (p[0] != '2' || p[1] != '5' || p[2] != '0') { return NGX_ERROR; } b->last = ngx_cpymem(b->pos, "AUTH LOGIN" CRLF, sizeof("AUTH LOGIN" CRLF) - 1); state = sw_login; break; case sw_login: if (p[0] != '3' || p[1] != '3' || p[2] != '4') { return NGX_ERROR; } src = ctx->user; dst.len = ngx_base64_encoded_length(src.len); dst.data = ngx_pnalloc(ctx->pool, dst.len); if (dst.data == NULL) { return NGX_ERROR; } ngx_encode_base64(&dst, &src); b->last = ngx_slprintf(b->pos, b->end, "%V" CRLF, &dst); state = sw_user; break; case sw_user: if (p[0] != '3' || p[1] != '3' || p[2] != '4') { return NGX_ERROR; } src = ctx->passwd; dst.len = ngx_base64_encoded_length(src.len); dst.data = ngx_pnalloc(ctx->pool, dst.len); if (dst.data == NULL) { return NGX_ERROR; } ngx_encode_base64(&dst, &src); b->last = ngx_slprintf(b->pos, b->end, "%V" CRLF, &dst); state = sw_passwd; break; case sw_passwd: if (p[0] != '2' || p[1] != '3' || p[2] != '5') { return NGX_ERROR; } b->last = ngx_slprintf(b->pos, b->end, "MAIL FROM:<%V>" CRLF, &ctx->from); state = sw_from; break; case sw_from: if (p[0] != '2' || p[1] != '5' || p[2] != '0') { return NGX_ERROR; } to = ctx->to.elts; b->last = ngx_slprintf(b->pos, b->end, "RCPT TO:<%V>" CRLF, &to[ctx->n++]); state = sw_to; break; case sw_to: if (p[0] != '2' || p[1] != '5' || p[2] != '0') { return NGX_ERROR; } if (ctx->n < ctx->to.nelts) { to = ctx->to.elts; b->last = ngx_slprintf(b->pos, b->end, "RCPT TO:<%V>" CRLF, &to[ctx->n++]); break; } b->last = ngx_cpymem(b->pos, "DATA" CRLF, sizeof("DATA" CRLF) - 1); state = sw_data; break; case sw_data: if (p[0] != '3' || p[1] != '5' || p[2] != '4') { return NGX_ERROR; } b->last = ngx_slprintf(b->pos, b->end, "Subject: %V" CRLF, &ctx->subject); to = ctx->to.elts; for (i = 0; i < ctx->to.nelts; i++) { b->last = ngx_slprintf(b->last, b->end, "To: %V" CRLF, &to[i]); } b->last = ngx_slprintf(b->last, b->end, CRLF "%V" CRLF "." CRLF, &ctx->content); state = sw_quit; break; case sw_quit: if (p[0] != '2' || p[1] != '5' || p[2] != '0') { return NGX_ERROR; } b->last = ngx_cpymem(b->pos, "QUIT" CRLF, sizeof("QUIT" CRLF) - 1); state = sw_done; break; case sw_done: if (p[0] != '2' || p[1] != '2' || p[2] != '1') { return NGX_ERROR; } return NGX_DONE; default: return NGX_ERROR; } ctx->state = state; ctx->peer.connection->read->handler = ngx_lua_smtp_dummy_handler; ctx->peer.connection->write->handler = ngx_lua_smtp_write_handler; ngx_lua_smtp_write_handler(ctx->peer.connection->write); return NGX_OK; }
void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, const char *fmt, va_list args) #endif { #if (NGX_HAVE_VARIADIC_MACROS) va_list args; #endif u_char *p, *last, *msg; u_char errstr[NGX_MAX_ERROR_STR]; if (log->file->fd == NGX_INVALID_FILE) { return; } last = errstr + NGX_MAX_ERROR_STR; ngx_memcpy(errstr, ngx_cached_err_log_time.data, ngx_cached_err_log_time.len); p = errstr + ngx_cached_err_log_time.len; p = ngx_slprintf(p, last, " [%V] ", &err_levels[level]); /* pid#tid */ p = ngx_slprintf(p, last, "%P#" NGX_TID_T_FMT ": ", ngx_log_pid, ngx_log_tid); if (log->connection) { p = ngx_slprintf(p, last, "*%uA ", log->connection); } msg = p; #if (NGX_HAVE_VARIADIC_MACROS) va_start(args, fmt); p = ngx_vslprintf(p, last, fmt, args); va_end(args); #else p = ngx_vslprintf(p, last, fmt, args); #endif if (err) { p = ngx_log_errno(p, last, err); } if (level != NGX_LOG_DEBUG && log->handler) { p = log->handler(log, p, last - p); } if (p > last - NGX_LINEFEED_SIZE) { p = last - NGX_LINEFEED_SIZE; } ngx_linefeed(p); (void) ngx_write_fd(log->file->fd, errstr, p - errstr); if (!ngx_use_stderr || level > NGX_LOG_WARN || log->file->fd == ngx_stderr) { return; } msg -= (err_levels[level].len + 4); (void) ngx_sprintf(msg, "[%V]: ", &err_levels[level]); (void) ngx_write_console(ngx_stderr, msg, p - msg); }
static void ngx_lua_http_connect_handler(ngx_event_t *wev) { size_t size; ngx_buf_t *b; ngx_uint_t i; ngx_keyval_t *headers; ngx_connection_t *c; ngx_lua_http_ctx_t *ctx; ngx_log_debug0(NGX_LOG_DEBUG_CORE, wev->log, 0, "lua http connect handler"); c = wev->data; ctx = c->data; if (wev->timedout) { ngx_log_error(NGX_LOG_ERR, wev->log, NGX_ETIMEDOUT, "lua http connecting %V timed out", ctx->peer.name); ngx_lua_http_finalize(ctx, "ngx_lua_http_connect_handler() timed out"); return; } if (wev->timer_set) { ngx_del_timer(wev); } c->read->handler = ngx_lua_http_dummy_handler; wev->handler = ngx_lua_http_write_handler; size = ctx->method.len + 1 + ctx->u.uri.len + 6 + ctx->version.len + 2 + sizeof("Host: ") - 1 + ctx->u.host.len + 1 + NGX_INT32_LEN + 2; headers = ctx->headers.elts; for (i = 0; i < ctx->headers.nelts; i++) { size += headers[i].key.len + 2 + headers[i].value.len + 2; } if (ctx->body.len) { size += sizeof("Content-Length: ") - 1 + NGX_INT32_LEN + 2; } size += 2 + ctx->body.len; b = ngx_create_temp_buf(ctx->pool, size); if (b == NULL) { ngx_lua_http_finalize(ctx, "ngx_create_temp_buf() failed"); return; } b->last = ngx_slprintf(b->last, b->end, "%V %V HTTP/%V" CRLF, &ctx->method, &ctx->u.uri, &ctx->version); b->last = ngx_slprintf(b->last, b->end, "Host: %V:%d" CRLF, &ctx->u.host, (int) ctx->u.port); for (i = 0; i < ctx->headers.nelts; i++) { b->last = ngx_slprintf(b->last, b->end, "%V: %V" CRLF, &headers[i].key, &headers[i].value); } if (ctx->body.len) { b->last = ngx_slprintf(b->last, b->end, "Content-Length: %uz" CRLF, ctx->body.len); } *b->last++ = CR; *b->last++ = LF; if (ctx->body.len) { b->last = ngx_cpymem(b->last, ctx->body.data, ctx->body.len); } ctx->request = b; ctx->headers.nelts = 0; ctx->response = ngx_create_temp_buf(ctx->pool, ngx_pagesize); if (ctx->response == NULL) { ngx_lua_http_finalize(ctx, "ngx_create_temp_buf() failed"); return; } ngx_lua_http_write_handler(wev); }
void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, const char *fmt, va_list args) #endif { #if (NGX_HAVE_VARIADIC_MACROS) va_list args; #endif u_char *p, *last, *msg; ssize_t n; ngx_uint_t wrote_stderr, debug_connection; u_char errstr[NGX_MAX_ERROR_STR]; // 错误消息的最大长度,2k字节 last = errstr + NGX_MAX_ERROR_STR; // 先拷贝当前的时间 // 格式是"1970/09/28 12:00:00" p = ngx_cpymem(errstr, ngx_cached_err_log_time.data, ngx_cached_err_log_time.len); // 打印错误等级的字符串描述信息,使用关联数组err_levels p = ngx_slprintf(p, last, " [%V] ", &err_levels[level]); // 打印pid和tid // #define ngx_log_pid ngx_pid // #define ngx_log_tid ngx_thread_tid() // in os/unix /* pid#tid */ p = ngx_slprintf(p, last, "%P#" NGX_TID_T_FMT ": ", ngx_log_pid, ngx_log_tid); // 如果有连接计数则打印 if (log->connection) { p = ngx_slprintf(p, last, "*%uA ", log->connection); } // 前面输出的是基本的信息:当前时间+[错误级别]+pid#tid: msg = p; // 打印可变参数 #if (NGX_HAVE_VARIADIC_MACROS) va_start(args, fmt); p = ngx_vslprintf(p, last, fmt, args); va_end(args); #else p = ngx_vslprintf(p, last, fmt, args); #endif // 如果有系统错误码,那么记录(err) if (err) { p = ngx_log_errno(p, last, err); } // 记录错误日志时可以执行的回调函数 // 参数是消息缓冲区里剩余的空间 // 只有高于debug才会执行 if (level != NGX_LOG_DEBUG && log->handler) { p = log->handler(log, p, last - p); } // #define NGX_LINEFEED_SIZE 1 if (p > last - NGX_LINEFEED_SIZE) { p = last - NGX_LINEFEED_SIZE; } // #define ngx_linefeed(p) *p++ = LF; ngx_linefeed(p); wrote_stderr = 0; debug_connection = (log->log_level & NGX_LOG_DEBUG_CONNECTION) != 0; // 对整个日志链表执行写入操作 while (log) { if (log->log_level < level && !debug_connection) { break; } if (log->writer) { log->writer(log, level, errstr, p - errstr); goto next; } if (ngx_time() == log->disk_full_time) { /* * on FreeBSD writing to a full filesystem with enabled softupdates * may block process for much longer time than writing to non-full * filesystem, so we skip writing to a log for one second */ goto next; } // 写错误日志消息到关联的文件 // 实际上就是系统调用write,见ngx_files.h n = ngx_write_fd(log->file->fd, errstr, p - errstr); // 写入失败,且错误是磁盘满 if (n == -1 && ngx_errno == NGX_ENOSPC) { log->disk_full_time = ngx_time(); } if (log->file->fd == ngx_stderr) { wrote_stderr = 1; } next: // 使用下一个日志对象记录日志 log = log->next; } if (!ngx_use_stderr || level > NGX_LOG_WARN || wrote_stderr) { return; } msg -= (7 + err_levels[level].len + 3); (void) ngx_sprintf(msg, "nginx: [%V] ", &err_levels[level]); (void) ngx_write_console(ngx_stderr, msg, p - msg); }
static ngx_int_t ngx_http_reqstat_show_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_buf_t *b; ngx_uint_t i, j; ngx_array_t *display; ngx_chain_t *tl, *free, *busy; ngx_queue_t *q; ngx_shm_zone_t **shm_zone; ngx_http_reqstat_ctx_t *ctx; ngx_http_reqstat_conf_t *slcf; ngx_http_reqstat_conf_t *smcf; ngx_http_reqstat_rbnode_t *node; slcf = ngx_http_get_module_loc_conf(r, ngx_http_reqstat_module); smcf = ngx_http_get_module_main_conf(r, ngx_http_reqstat_module); display = slcf->display == NULL ? smcf->monitor : slcf->display; if (display == NULL) { r->headers_out.status = NGX_HTTP_NO_CONTENT; return ngx_http_send_header(r); } r->headers_out.status = NGX_HTTP_OK; ngx_http_clear_content_length(r); rc = ngx_http_send_header(r); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { return rc; } shm_zone = display->elts; for (free = busy = NULL, i = 0; i < display->nelts; i++) { ctx = shm_zone[i]->data; for (q = ngx_queue_head(&ctx->sh->queue); q != ngx_queue_sentinel(&ctx->sh->queue); q = ngx_queue_next(q)) { node = ngx_queue_data(q, ngx_http_reqstat_rbnode_t, queue); tl = ngx_chain_get_free_buf(r->pool, &free); if (tl == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } b = tl->buf; if (b->start == NULL) { b->start = ngx_pcalloc(r->pool, 512); if (b->start == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } b->end = b->start + 512; } b->last = b->pos = b->start; b->memory = 1; b->temporary = 1; b->last = ngx_slprintf(b->last, b->end, "%*s,", (size_t) node->len, node->data); for (j = 0; j < sizeof(ngx_http_reqstat_fields) / sizeof(off_t); j++) { b->last = ngx_slprintf(b->last, b->end, "%uA,", *REQ_FIELD(node, ngx_http_reqstat_fields[j])); } *(b->last - 1) = '\n'; if (ngx_http_output_filter(r, tl) == NGX_ERROR) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } #if nginx_version >= 1002000 ngx_chain_update_chains(r->pool, &free, &busy, &tl, (ngx_buf_tag_t) &ngx_http_reqstat_module); #else ngx_chain_update_chains(&free, &busy, &tl, (ngx_buf_tag_t) &ngx_http_reqstat_module); #endif } } tl = ngx_chain_get_free_buf(r->pool, &free); if (tl == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } b = tl->buf; b->last_buf = 1; return ngx_http_output_filter(r, tl); }
void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, const char *fmt, ...){ #else void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, const char *fmt, va_list args){ #endif #if (NGX_HAVE_VARIADIC_MACROS) va_list args; #endif u_char *p,*last,*msg; ssize_t n; ngx_uint_t wrote_stderr,debug_connection; u_char errstr[NGX_MAX_ERROR_STR]; last = errstr + NGX_MAX_ERROR_STR; //it seems do not set the ngx_cached_err_log_time.len value p = ngx_cpymem(errstr,ngx_cached_err_log_time.data, ngx_cached_err_log_time.len); p = ngx_slprintf(p,last,"[%V]",&err_levels[level]); //just for making the datastructure can work correctly,comment the next function /* pid#tid */ // p = ngx_slprintf(p,last,"%P#" NGX_TID_T_FMT ": ", // ngx_log_pid,ngx_log_tid); if (log->connection) { p = ngx_slprintf(p,last,"*%uA ",log->connection); } msg = p; #if (NGX_HAVE_VARIADIC_MACROS) va_start (args,fmt); p = ngx_vslprintf(p,last,fmt,args); va_end (args); #else p = ngx_vslprintf(p,last,fmt,args); #endif if (err) { p = ngx_log_errno(p,last,err); } if (level != NGX_LOG_DEBUG && log->handler){ p = log->handler(log,p,last - p); } if (p > last - NGX_LINEFEED_SIZE){ p = last - NGX_LINEFEED_SIZE; } ngx_linefeed(p); wrote_stderr = 0; debug_connection = (log->log_level & NGX_LOG_DEBUG_CONNECTION) != 0; while(log){ if (log->log_level < level && !debug_connection){ break; } if(log->writer){ log->writer(log,level,errstr,p - errstr); goto next; } if (ngx_time() == log->disk_full_time){ /* * on FreeBSD writing to a full filesystem with enabled softupdates * may block process for much longer time than writing to non-full * filesystem, so we skip writing to a log for one second */ goto next; } n = ngx_write_fd(log->file->fd,errstr,p - errstr); if (n == -1 && ngx_errno == NGX_ENOSPC){ log->disk_full_time = ngx_time(); } if (log->file->fd == ngx_stderr){ wrote_stderr = 1; } next: log = log->next; } if (!ngx_use_stderr || level > NGX_LOG_WARN || wrote_stderr){ return; } msg -= (7 + err_levels[level].len + 3); (void)ngx_sprintf(msg,"nginx: [%V]",&err_levels[level]); (void) ngx_write_console(ngx_stderr,msg,p - msg); }
ngx_int_t ngx_http_xray_body_output_filter(ngx_http_request_t *r, ngx_chain_t *in) { ngx_chain_t *cl; ngx_http_xray_ctx_t *xctx = ngx_http_get_module_ctx(r, ngx_http_xray_module); if (in == NULL || r->header_only) { return next_body_filter(r, in); } if (!xctx || !xctx->xray || xctx->xray->last == xctx->xray->start) { /* nothing to be done */ return next_body_filter(r, in); } if (xctx->xray_chained) { return next_body_filter(r, in); } xctx->xray_chained = 1; ngx_log_debug(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "prepending %i bytes of xray data", xctx->xray->last - xctx->xray->start); cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ngx_alloc_chain_link failed"); return NGX_HTTP_INTERNAL_SERVER_ERROR; } xctx->xray->memory = 1; cl->buf = xctx->xray; cl->next = in; in = cl; // if the request is not chunked, done if (r->headers_out.content_length_n >= 0) { return next_body_filter(r, in); } if (!r->chunked) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "content_length_n=%i but r->chunked=%i. Skipping xray append.", r->headers_out.content_length_n, (ngx_int_t) r->chunked); return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_log_debug(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "response is chunked"); // allocate and prepend the chunk header cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ngx_alloc_chain_link failed"); return NGX_HTTP_INTERNAL_SERVER_ERROR; } cl->buf = ngx_create_temp_buf(r->pool, 32); // enough for length + CRLF if (cl->buf == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ngx_create_temp_buf failed"); return NGX_HTTP_INTERNAL_SERVER_ERROR; } cl->buf->memory = 1; cl->buf->last = ngx_slprintf(cl->buf->start, cl->buf->end, "%xO" CRLF, xctx->xray->last - xctx->xray->start); ngx_log_debug(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "added chunk length header: %xO", xctx->xray->last - xctx->xray->start); // in->buf is pointing at the non-NULL Xray body, append a CRLF to the end if (in->buf->end - in->buf->last < 2) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "insufficient space in xray buffer to append CRLF"); return NGX_HTTP_INTERNAL_SERVER_ERROR; } *(in->buf->last++) = CR; *(in->buf->last++) = LF; cl->next = in; in = cl; return next_body_filter(r, in); }
void ngx_log_error_core(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, const char *fmt, va_list args) #endif { #if (NGX_HAVE_VARIADIC_MACROS) va_list args; #endif u_char *p, *last, *msg; u_char errstr[NGX_MAX_ERROR_STR]; ngx_uint_t wrote_stderr, debug_connection; last = errstr + NGX_MAX_ERROR_STR; ngx_memcpy(errstr, ngx_cached_err_log_time.data, ngx_cached_err_log_time.len); p = errstr + ngx_cached_err_log_time.len; p = ngx_slprintf(p, last, " [%V] ", &err_levels[level]); /* pid#tid */ p = ngx_slprintf(p, last, "%P#" NGX_TID_T_FMT ": ", ngx_log_pid, ngx_log_tid); if (log->connection) { p = ngx_slprintf(p, last, "*%uA ", log->connection); } msg = p; #if (NGX_HAVE_VARIADIC_MACROS) va_start(args, fmt); p = ngx_vslprintf(p, last, fmt, args); va_end(args); #else p = ngx_vslprintf(p, last, fmt, args); #endif if (err) { p = ngx_log_errno(p, last, err); } if (level != NGX_LOG_DEBUG && log->handler) { p = log->handler(log, p, last - p); } if (p > last - NGX_LINEFEED_SIZE) { p = last - NGX_LINEFEED_SIZE; } ngx_linefeed(p); wrote_stderr = 0; debug_connection = (log->log_level & NGX_LOG_DEBUG_CONNECTION) != 0; while (log) { if (log->log_level < level && !debug_connection) { break; } (void) ngx_write_fd(log->file->fd, errstr, p - errstr); if (log->file->fd == ngx_stderr) { wrote_stderr = 1; } log = log->next; } if (!ngx_use_stderr || level > NGX_LOG_WARN || wrote_stderr) { return; } //ginozhang //msg -= (7 + err_levels[level].len + 3); //(void) ngx_sprintf(msg, "nginx: [%V] ", &err_levels[level]); msg -= (6 + err_levels[level].len + 3); (void) ngx_sprintf(msg, "scan: [%V] ", &err_levels[level]); (void) ngx_write_console(ngx_stderr, msg, p - msg); }
static ngx_int_t ngx_http_touch_handler(ngx_http_request_t *r) { //main config ngx_http_upstream_main_conf_t * umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); //server config //ngx_http_upstream_srv_conf_t * umsf = r->srv_conf[ngx_http_upstream_module.ctx_index]; //location config //ngx_http_core_loc_conf_t * hclf = (*(r->loc_conf)); ngx_http_upstream_srv_conf_t **uscfp, *uscf; ngx_uint_t i, j, len; u_char *p, *b; ngx_chain_t *cl; ngx_http_upstream_server_t *us; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "ngx_http_touch_handler"); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "umcfaddress=%d", umcf); if (umcf == NULL || umcf->upstreams.nelts <= 0) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "NGX_HTTP_NO_CONTENT"); return NGX_HTTP_NO_CONTENT; } //response content buffer length len = 1024 * 16; p = b = ngx_palloc(r->pool, len); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "umcf->upstreams.nelts=%ui\n", umcf->upstreams.nelts); ngx_http_variable_value_t *upstreamname, *servername; ngx_uint_t hash; hash = ngx_hash_key(arg_upstream.data, arg_upstream.len); upstreamname = ngx_http_get_variable(r, &arg_upstream, hash); hash = ngx_hash_key(arg_server.data, arg_server.len); servername = ngx_http_get_variable(r, &arg_server, hash); p = ngx_slprintf(p, b + len, "Worker id: %P\n", ngx_pid); uscfp = umcf->upstreams.elts; for (i = 0; i < umcf->upstreams.nelts; i++) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "i=%d", i); uscf = uscfp[i]; // ngx_slprintf(start, last, fmt, args) p = ngx_slprintf(p, b + len, "upstream name: %V\n", &uscf->host); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "upstream name:%V", &uscf->host); if(uscf->servers != NULL && uscf->servers->nelts > 0) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "uscf->servers->nelts = %ui", uscf->servers->nelts); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "uscf->servers->size = %ui", uscf->servers->size); for (j = 0; j < uscf->servers->nelts; j++) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "j=%d", j); //us = (ngx_http_upstream_server_t *)(uscf->servers->elts + j * uscf->servers->size); us = (ngx_http_upstream_server_t *)uscf->servers->elts + j; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "us=%d", us); if (us != NULL) { if (upstreamname && upstreamname->not_found == 0 && servername && servername->not_found == 0 && ngx_strncmp(upstreamname->data, uscf->host.data, upstreamname->len) == 0 && ngx_strncmp(servername->data, us->addrs->name.data, servername->len) == 0) { ngx_http_touch_set_upstream_server(r, us, uscf); } ngx_log_debug6(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "usaddress=%d, weight=%d, max_fails=%d, fail_timeout=%d, down=%d, backup=%d", us, us->weight, us->max_fails, us->fail_timeout, us->down, us->backup); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "server name=%V", &us->addrs->name); if (us->addrs != NULL) { // socket to string // parameters :sockaddr, start, max_length, port print? p += ngx_sock_ntop(us->addrs->sockaddr, p, b - p + len, 1); } p = ngx_slprintf(p, b + len, " weight=%d, max_fails=%d, fail_timeout=%d, down=%d, backup=%d\n", us->weight, us->max_fails, us->fail_timeout, us->down, us->backup); } } } } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 1, "ngx_alloc_chain_link"); cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 1, "ngx_alloc_chain_link error"); return NGX_ERROR; } cl->next = NULL; cl->buf = ngx_calloc_buf(r->pool); ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 1, "ngx_calloc_buf"); if (cl->buf == NULL) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 1, "ngx_calloc_buf error"); return NGX_ERROR; } cl->buf->pos = b; cl->buf->last = p; cl->buf->last_buf = 1;/* this is last , and there will be no more buffers in the request */ cl->buf->memory = 1; /* content is in read-only memory */ /* (i.e., filters should copy it rather than rewrite in place) */ r->headers_out.content_length_n = p - b; r->headers_out.status = NGX_HTTP_OK; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 1, "ngx_http_send_header(r)"); if (ngx_http_send_header(r) != NGX_OK) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 1, "ngx_http_send_header(r) error"); return NGX_ERROR; } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 1, "ngx_http_output_filter"); return ngx_http_output_filter(r, cl); }