#define BF_SHUTR_DONE 2
#define BF_SHUTW_PENDING 4
#define BF_SHUTW_DONE 8
+
#define BF_PARTIAL_READ 16
#define BF_COMPLETE_READ 32
#define BF_READ_ERROR 64
-#define BF_PARTIAL_WRITE 128
-#define BF_COMPLETE_WRITE 256
-#define BF_WRITE_ERROR 512
+#define BF_READ_NULL 128
+#define BF_READ_STATUS (BF_PARTIAL_READ|BF_COMPLETE_READ|BF_READ_ERROR|BF_READ_NULL)
+#define BF_CLEAR_READ (~BF_READ_STATUS)
+
+#define BF_PARTIAL_WRITE 256
+#define BF_COMPLETE_WRITE 512
+#define BF_WRITE_ERROR 1024
+#define BF_WRITE_NULL 2048
+#define BF_WRITE_STATUS (BF_PARTIAL_WRITE|BF_COMPLETE_WRITE|BF_WRITE_ERROR|BF_WRITE_NULL)
+#define BF_CLEAR_WRITE (~BF_WRITE_STATUS)
};
struct buffer {
- u_int32_t flags;
+ u_int32_t flags; /* BF_* */
unsigned int l; /* data length */
char *r, *w, *h, *lr; /* read ptr, write ptr, last header ptr, last read */
char *rlim; /* read limit, used for header rewriting */
if (s->cli_state != CL_STCLOSE || s->srv_state != SV_STCLOSE) {
struct timeval min1, min2;
- s->res_cw = s->res_cr = s->res_sw = s->res_sr = RES_SILENT;
+ s->req->flags &= BF_CLEAR_READ & BF_CLEAR_WRITE;
+ s->rep->flags &= BF_CLEAR_READ & BF_CLEAR_WRITE;
tv_min(&min1, &s->crexpire, &s->cwexpire);
tv_min(&min2, &s->srexpire, &s->swexpire);
t->flags |= SN_FINST_R;
return 1;
}
- else if (t->res_cr == RES_ERROR || t->res_cr == RES_NULL) {
+ else if (req->flags & (BF_READ_ERROR | BF_READ_NULL)) {
/* read error, or last read : give up. */
tv_eternity(&t->crexpire);
fd_delete(t->cli_fd);
* we're waiting for the server to connect.
*/
/* read or write error */
- if (t->res_cw == RES_ERROR || t->res_cr == RES_ERROR) {
+ if (rep->flags & BF_WRITE_ERROR || req->flags & BF_READ_ERROR) {
tv_eternity(&t->crexpire);
tv_eternity(&t->cwexpire);
fd_delete(t->cli_fd);
return 1;
}
/* last read, or end of server write */
- else if (t->res_cr == RES_NULL || s == SV_STSHUTW || s == SV_STCLOSE) {
+ else if (req->flags & BF_READ_NULL || s == SV_STSHUTW || s == SV_STCLOSE) {
FD_CLR(t->cli_fd, StaticReadEvent);
tv_eternity(&t->crexpire);
shutdown(t->cli_fd, SHUT_RD);
return 0; /* other cases change nothing */
}
else if (c == CL_STSHUTR) {
- if (t->res_cw == RES_ERROR) {
+ if (rep->flags & BF_WRITE_ERROR) {
tv_eternity(&t->cwexpire);
fd_delete(t->cli_fd);
t->cli_state = CL_STCLOSE;
return 0;
}
else if (c == CL_STSHUTW) {
- if (t->res_cr == RES_ERROR) {
+ if (req->flags & BF_READ_ERROR) {
tv_eternity(&t->crexpire);
fd_delete(t->cli_fd);
t->cli_state = CL_STCLOSE;
}
return 1;
}
- else if (t->res_cr == RES_NULL || s == SV_STSHUTW || s == SV_STCLOSE) {
+ else if (req->flags & BF_READ_NULL || s == SV_STSHUTW || s == SV_STCLOSE) {
tv_eternity(&t->crexpire);
fd_delete(t->cli_fd);
t->cli_state = CL_STCLOSE;
srv_close_with_err(t, SN_ERR_CLICL, SN_FINST_C, 0, 0, NULL);
return 1;
}
- if (t->res_sw == RES_SILENT && tv_cmp2_ms(&t->cnexpire, &now) > 0) {
+ if (!(req->flags & BF_WRITE_STATUS) && tv_cmp2_ms(&t->cnexpire, &now) > 0) {
//fprintf(stderr,"1: c=%d, s=%d, now=%d.%06d, exp=%d.%06d\n", c, s, now.tv_sec, now.tv_usec, t->cnexpire.tv_sec, t->cnexpire.tv_usec);
return 0; /* nothing changed */
}
- else if (t->res_sw == RES_SILENT || t->res_sw == RES_ERROR) {
+ else if (!(req->flags & BF_WRITE_STATUS) || (req->flags & BF_WRITE_ERROR)) {
/* timeout, asynchronous connect error or first write error */
//fprintf(stderr,"2: c=%d, s=%d\n", c, s);
if (t->srv)
t->srv->cur_sess--;
- if (t->res_sw == RES_SILENT)
+ if (!(req->flags & BF_WRITE_STATUS))
conn_err = SN_ERR_SRVTO; // it was a connect timeout.
else
conn_err = SN_ERR_SRVCL; // it was an asynchronous connect error.
}
/* read error, write error */
- if (t->res_sw == RES_ERROR || t->res_sr == RES_ERROR) {
+ if (req->flags & BF_WRITE_ERROR || rep->flags & BF_READ_ERROR) {
tv_eternity(&t->srexpire);
tv_eternity(&t->swexpire);
fd_delete(t->srv_fd);
* since we are in header mode, if there's no space left for headers, we
* won't be able to free more later, so the session will never terminate.
*/
- else if (t->res_sr == RES_NULL || c == CL_STSHUTW || c == CL_STCLOSE || rep->l >= rep->rlim - rep->data) {
+ else if (rep->flags & BF_READ_NULL || c == CL_STSHUTW || c == CL_STCLOSE || rep->l >= rep->rlim - rep->data) {
FD_CLR(t->srv_fd, StaticReadEvent);
tv_eternity(&t->srexpire);
shutdown(t->srv_fd, SHUT_RD);
}
else if (s == SV_STDATA) {
/* read or write error */
- if (t->res_sw == RES_ERROR || t->res_sr == RES_ERROR) {
+ if (req->flags & BF_WRITE_ERROR || rep->flags & BF_READ_ERROR) {
tv_eternity(&t->srexpire);
tv_eternity(&t->swexpire);
fd_delete(t->srv_fd);
return 1;
}
/* last read, or end of client write */
- else if (t->res_sr == RES_NULL || c == CL_STSHUTW || c == CL_STCLOSE) {
+ else if (rep->flags & BF_READ_NULL || c == CL_STSHUTW || c == CL_STCLOSE) {
FD_CLR(t->srv_fd, StaticReadEvent);
tv_eternity(&t->srexpire);
shutdown(t->srv_fd, SHUT_RD);
return 0; /* other cases change nothing */
}
else if (s == SV_STSHUTR) {
- if (t->res_sw == RES_ERROR) {
+ if (req->flags & BF_WRITE_ERROR) {
//FD_CLR(t->srv_fd, StaticWriteEvent);
tv_eternity(&t->swexpire);
fd_delete(t->srv_fd);
return 0;
}
else if (s == SV_STSHUTW) {
- if (t->res_sr == RES_ERROR) {
+ if (rep->flags & BF_READ_ERROR) {
//FD_CLR(t->srv_fd, StaticReadEvent);
tv_eternity(&t->srexpire);
fd_delete(t->srv_fd);
return 1;
}
- else if (t->res_sr == RES_NULL || c == CL_STSHUTW || c == CL_STCLOSE) {
+ else if (rep->flags & BF_READ_NULL || c == CL_STSHUTW || c == CL_STCLOSE) {
//FD_CLR(t->srv_fd, StaticReadEvent);
tv_eternity(&t->srexpire);
fd_delete(t->srv_fd);
if (ret > 0) {
b->r += ret;
b->l += ret;
- s->res_cr = RES_DATA;
+ b->flags |= BF_PARTIAL_READ;
if (b->r == b->data + BUFSIZE) {
b->r = b->data; /* wrap around the buffer */
continue;
}
else if (ret == 0) {
- s->res_cr = RES_NULL;
+ b->flags |= BF_READ_NULL;
break;
}
else if (errno == EAGAIN) {/* ignore EAGAIN */
break;
}
else {
- s->res_cr = RES_ERROR;
+ b->flags |= BF_READ_ERROR;
fdtab[fd].state = FD_STERROR;
break;
}
#endif
}
else {
- s->res_cr = RES_ERROR;
+ b->flags |= BF_READ_ERROR;
fdtab[fd].state = FD_STERROR;
}
- if (s->res_cr != RES_SILENT) {
+ if (b->flags & BF_READ_STATUS) {
if (s->proxy->clitimeout && FD_ISSET(fd, StaticReadEvent))
tv_delayfrom(&s->crexpire, &now, s->proxy->clitimeout);
else
if (fdtab[fd].state != FD_STERROR) {
if (max == 0) {
- s->res_cw = RES_NULL;
+ b->flags |= BF_WRITE_NULL;
task_wakeup(&rq, t);
tv_eternity(&s->cwexpire);
FD_CLR(fd, StaticWriteEvent);
b->l -= ret;
b->w += ret;
- s->res_cw = RES_DATA;
+ b->flags |= BF_PARTIAL_WRITE;
if (b->w == b->data + BUFSIZE) {
b->w = b->data; /* wrap around the buffer */
}
else if (ret == 0) {
/* nothing written, just make as if we were never called */
- // s->res_cw = RES_NULL;
+ // b->flags |= BF_WRITE_NULL;
return 0;
}
else if (errno == EAGAIN) /* ignore EAGAIN */
return 0;
else {
- s->res_cw = RES_ERROR;
+ b->flags |= BF_WRITE_ERROR;
fdtab[fd].state = FD_STERROR;
}
}
else {
- s->res_cw = RES_ERROR;
+ b->flags |= BF_WRITE_ERROR;
fdtab[fd].state = FD_STERROR;
}
if (ret > 0) {
b->r += ret;
b->l += ret;
- s->res_sr = RES_DATA;
+ b->flags |= BF_PARTIAL_READ;
if (b->r == b->data + BUFSIZE) {
b->r = b->data; /* wrap around the buffer */
continue;
}
else if (ret == 0) {
- s->res_sr = RES_NULL;
+ b->flags |= BF_READ_NULL;
break;
}
else if (errno == EAGAIN) {/* ignore EAGAIN */
break;
}
else {
- s->res_sr = RES_ERROR;
+ b->flags |= BF_READ_ERROR;
fdtab[fd].state = FD_STERROR;
break;
}
#endif
}
else {
- s->res_sr = RES_ERROR;
+ b->flags |= BF_READ_ERROR;
fdtab[fd].state = FD_STERROR;
}
- if (s->res_sr != RES_SILENT) {
+ if (b->flags & BF_READ_STATUS) {
if (s->proxy->srvtimeout && FD_ISSET(fd, StaticReadEvent))
tv_delayfrom(&s->srexpire, &now, s->proxy->srvtimeout);
else
socklen_t lskerr = sizeof(skerr);
getsockopt(fd, SOL_SOCKET, SO_ERROR, &skerr, &lskerr);
if (skerr) {
- s->res_sw = RES_ERROR;
+ b->flags |= BF_WRITE_ERROR;
fdtab[fd].state = FD_STERROR;
task_wakeup(&rq, t);
tv_eternity(&s->swexpire);
}
}
- s->res_sw = RES_NULL;
+ b->flags |= BF_WRITE_NULL;
task_wakeup(&rq, t);
fdtab[fd].state = FD_STREADY;
tv_eternity(&s->swexpire);
b->l -= ret;
b->w += ret;
- s->res_sw = RES_DATA;
+ b->flags |= BF_PARTIAL_WRITE;
if (b->w == b->data + BUFSIZE) {
b->w = b->data; /* wrap around the buffer */
}
else if (ret == 0) {
/* nothing written, just make as if we were never called */
- // s->res_sw = RES_NULL;
+ // b->flags |= BF_WRITE_NULL;
return 0;
}
else if (errno == EAGAIN) /* ignore EAGAIN */
return 0;
else {
- s->res_sw = RES_ERROR;
+ b->flags |= BF_WRITE_ERROR;
fdtab[fd].state = FD_STERROR;
}
}
else {
- s->res_sw = RES_ERROR;
+ b->flags |= BF_WRITE_ERROR;
fdtab[fd].state = FD_STERROR;
}