📄 response.c
字号:
fprintf(stderr,"%03d/%d: send range: %ld-%ld/%ld (%ld byte)\n",#else fprintf(stderr,"%03d/%d: send range: %lld-%lld/%lld (%lld byte)\n", #endif req->fd, req->state, req->r_start[i],req->r_end[i],req->bst.st_size, req->r_end[i]-req->r_start[i]);#endif return req->r_hlen[i];}void mkheader(struct REQUEST *req, int status, time_t mtime){ int i; off_t len; time_t expires; for (i = 0; http[i].status != 0; i++) { if (http[i].status == status) { break; } } req->status = status; req->lres = sprintf(req->hres, RESPONSE_START, http[i].head,server_name, req->keep_alive ? "Keep-Alive" : "Close"); if (req->ranges == 0) { req->lres += sprintf(req->hres+req->lres, "Content-Type: %s\r\n"#if (SIZEOF_OFF_T == 4) "Content-Length: %ld\r\n",#else "Content-Length: %lld\r\n",#endif req->mime, req->body ? req->lbody : req->bst.st_size); } else if (req->ranges == 1) { req->lres += sprintf(req->hres+req->lres, "Content-Type: %s\r\n"#if (SIZEOF_OFF_T == 4) "Content-Range: bytes %ld-%ld/%ld\r\n" "Content-Length: %ld\r\n",#else "Content-Range: bytes %lld-%lld/%lld\r\n" "Content-Length: %lld\r\n", #endif req->mime, req->r_start[0],req->r_end[0]-1,req->bst.st_size, req->r_end[0]-req->r_start[0]); } else { for (i = 0, len = 0; i < req->ranges; i++) { len += mkmulti(req,i); len += req->r_end[i]-req->r_start[i]; } req->r_hlen[i] = sprintf(req->r_head+i*BR_HEADER, "\r\n--" BOUNDARY "--\r\n", (unsigned long)now); len += req->r_hlen[i]; req->lres += sprintf(req->hres+req->lres, "Content-Type: multipart/byteranges;" " boundary=" BOUNDARY "\r\n"#if (SIZEOF_OFF_T == 4) "Content-Length: %ld\r\n",#else "Content-Length: %lld\r\n",#endif (unsigned long)now,len); } if (mtime != -1) { req->lres += strftime(req->hres+req->lres,80, "Last-Modified: " RFCTIME "\r\n", gmtime(&mtime)); if (req->lifespan != -1) { expires = mtime + req->lifespan; req->lres += strftime(req->hres+req->lres,80, "Expires: " RFCTIME "\r\n", gmtime(&expires)); } } req->lres += strftime(req->hres+req->lres,80, "Date: " RFCTIME "\r\n\r\n", gmtime(&now)); req->state = STATE_WRITE_HEADER;#ifdef DEBUG fprintf(stderr,"%03d/%d: %d, connection=%s\n", req->fd, req->state, status, req->keep_alive ? "Keep-Alive" : "Close");#endif}void write_request(struct REQUEST *req){ int rc; for (;;) { switch (req->state) { case STATE_WRITE_HEADER:#ifdef TCP_CORK if (req->tcp_cork == 0 && !req->head_only) { req->tcp_cork = 1;#ifdef DEBUG fprintf(stderr,"%03d/%d: tcp_cork=%d\n",req->fd,req->state,req->tcp_cork);#endif setsockopt(req->fd,SOL_TCP,TCP_CORK,&req->tcp_cork,sizeof(int)); }#endif rc = wrap_write(req,req->hres + req->written, req->lres - req->written); switch (rc) { case -1: if (errno == EAGAIN) { return; } if (errno == EINTR) { continue; } log_error_func(1,LOG_INFO,"write",req->peerhost); /* fall through */ case 0: req->state = STATE_CLOSE; return; default: req->written += rc; req->bc += rc; if (req->written != req->lres) { return; } } req->written = 0; if (req->head_only) { req->state = STATE_FINISHED; return; } else if (req->body) { req->state = STATE_WRITE_BODY; } else if (req->ranges == 1) { req->state = STATE_WRITE_RANGES; req->rh = -1; req->rb = 0; req->written = req->r_start[0]; } else if (req->ranges > 1) { req->state = STATE_WRITE_RANGES; req->rh = 0; req->rb = -1; } else { req->state = STATE_WRITE_FILE; } break; case STATE_WRITE_BODY: rc = wrap_write(req,req->body + req->written, req->lbody - req->written); switch (rc) { case -1: if (errno == EAGAIN) { return; } if (errno == EINTR) { continue; } log_error_func(1,LOG_INFO,"write",req->peerhost); /* fall through */ case 0: req->state = STATE_CLOSE; return; default: req->written += rc; req->bc += rc; if (req->written != req->lbody) { return; } } req->state = STATE_FINISHED; return; case STATE_WRITE_FILE: rc = wrap_xsendfile(req, req->written, req->bst.st_size - req->written); switch (rc) { case -1: if (errno == EAGAIN) { return; } if (errno == EINTR) { continue; } log_error_func(1,LOG_INFO,"sendfile",req->peerhost); /* fall through */ case 0: req->state = STATE_CLOSE; return; default:#ifdef DEBUG#if (SIZEOF_OFF_T == 4) fprintf(stderr,"%03d/%d: %ld/%ld (%ld%%)\r",req->fd,req->state,#else fprintf(stderr,"%03d/%d: %lld/%lld (%lld%%)\r",req->fd,req->state,#endif req->written,req->bst.st_size, req->written*100/req->bst.st_size);#endif req->written += rc; req->bc += rc; if (req->written != req->bst.st_size) { return; } } req->state = STATE_FINISHED; return; case STATE_WRITE_RANGES: if (-1 != req->rh) { /* write header */ rc = wrap_write(req, req->r_head + req->rh*BR_HEADER + req->written, req->r_hlen[req->rh] - req->written); switch (rc) { case -1: if (errno == EAGAIN) { return; } if (errno == EINTR) { continue; } log_error_func(1,LOG_INFO,"write",req->peerhost); /* fall through */ case 0: req->state = STATE_CLOSE; return; default: req->written += rc; req->bc += rc; if (req->written != req->r_hlen[req->rh]) { return; } } if (req->rh == req->ranges) { /* done -- no more ranges */ req->state = STATE_FINISHED; return; } /* prepare for body writeout */ req->rb = req->rh; req->rh = -1; req->written = req->r_start[req->rb]; } if (req->rb != -1) { /* write body */ rc = wrap_xsendfile(req, req->written, req->r_end[req->rb] - req->written); switch (rc) { case -1: if (errno == EAGAIN) { return; } if (errno == EINTR) { continue; } log_error_func(1,LOG_INFO,"sendfile",req->peerhost); /* fall through */ case 0: req->state = STATE_CLOSE; return; default: req->written += rc; req->bc += rc; if (req->written != req->r_end[req->rb]) { return; } } /* prepare for next subheader writeout */ req->rh = req->rb+1; req->rb = -1; req->written = 0; if (req->ranges == 1) { /* single range only */ req->state = STATE_FINISHED; return; } } break; } /* switch(state) */ } /* for (;;) */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -