diff --git a/core/sendfile.c b/core/sendfile.c index 1bf63202..1febd5c7 100644 --- a/core/sendfile.c +++ b/core/sendfile.c @@ -13,10 +13,6 @@ int uwsgi_offload_request_do(struct wsgi_request *wsgi_req, char *filename, size // avoid closing the connection wsgi_req->fd_closed = 1; -#ifdef TCP_CORK - // enable CORK mode (if available) -#endif - // fill offload request struct uwsgi_offload_request uor; uor.fd = open(filename, O_RDONLY | O_NONBLOCK); @@ -32,6 +28,9 @@ int uwsgi_offload_request_do(struct wsgi_request *wsgi_req, char *filename, size uor.prev = NULL; uor.next = NULL; + // put socket in non-blocking mode + uwsgi_socket_nb(uor.s); + if (write(uwsgi.offload_thread->pipe[0], &uor, sizeof(struct uwsgi_offload_request)) != sizeof(struct uwsgi_offload_request)) { goto error2; } diff --git a/plugins/http/http.c b/plugins/http/http.c index 9e252416..1e1612e8 100644 --- a/plugins/http/http.c +++ b/plugins/http/http.c @@ -1050,7 +1050,7 @@ ssize_t uwsgi_http_nb_send(struct uwsgi_corerouter *cr, struct corerouter_sessio struct http_session *hs = (struct http_session *) cs; ssize_t ret = write(cs->fd, buf, len); if (ret == (ssize_t) len) { - if (cs->instance_stopped) { + if (cs->instance_fd != -1 && cs->instance_stopped) { event_queue_add_fd_read(cr->queue, cs->instance_fd); cs->instance_stopped = 0; } @@ -1065,7 +1065,7 @@ ssize_t uwsgi_http_nb_send(struct uwsgi_corerouter *cr, struct corerouter_sessio } else if (ret < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { - if (cs->instance_fd != -1) { + if (cs->instance_fd != -1 && !cs->instance_stopped) { event_queue_del_fd(cr->queue, cs->instance_fd, event_queue_read()); cs->instance_stopped = 1; } @@ -1083,10 +1083,13 @@ ssize_t uwsgi_http_nb_send(struct uwsgi_corerouter *cr, struct corerouter_sessio // partial write hs->buffer_len -= ret; memcpy(hs->buffer, hs->buffer + ret, hs->buffer_len); - if (cs->instance_fd != -1) { + // stop reading from the instance + if (cs->instance_fd != -1 && !cs->instance_stopped) { event_queue_del_fd(cr->queue, cs->instance_fd, event_queue_read()); cs->instance_stopped = 1; } + + // wait for write from client if (!cs->fd_state) { event_queue_fd_read_to_write(cr->queue, cs->fd); cs->fd_state = 1; diff --git a/tests/t/static.pl b/tests/t/static.pl new file mode 100644 index 00000000..9b769516 --- /dev/null +++ b/tests/t/static.pl @@ -0,0 +1,82 @@ +use IO::Socket::INET; +use Digest::MD5 qw(md5) ; + +$NUM = 50; + +my @commands; + +push @commands, "./uwsgi --http-socket :9191 --disable-logging --static-offload-to-thread 64 --static-map /foobar=./t_foobar.txt --pidfile ./t_foobar.pid &"; +push @commands, "./uwsgi --http-socket :9191 --disable-logging -M -p 4 --static-offload-to-thread 64 --static-map /foobar=./t_foobar.txt --pidfile ./t_foobar.pid &"; +push @commands, "./uwsgi --http :9191 --disable-logging --static-map /foobar=./t_foobar.txt --static-offload-to-thread 64 --pidfile ./t_foobar.pid &"; + +print "generating random data for the test...\n"; + +my $content = generate_random_content(1024*1024); +my $first_digest = md5($content); + +open FOOBAR,'>t_foobar.txt'; +print FOOBAR $content; +close FOOBAR; + +foreach my $cmd(@commands) { + + system $cmd; + sleep(1); + + + my @s; + + print "sending requests to uWSGI...\n"; + + for(my $i=0;$i<$NUM;$i++) { + $s[$i] = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => 9191); + $s[$i]->send("GET /foobar HTTP/1.0\r\nHost: 127.0.0.1:9191\r\n\r\n"); + } + + my @body; + + print "receiving responses from uWSGI...\n"; + + while(1) { + $end = 0; + for(my $i=0;$i<$NUM;$i++) { + $s[$i]->recv(my $buf, 32768); + $end++ unless $buf; + $body[$i].=$buf; + } + last if $end >= $NUM; + } + + print "checking uWSGI responses...\n"; + + foreach my $data (@body) { + $data =~ s/^(.|\n|\r)*\r\n\r\n//m; + if (md5($data) ne $first_digest) { + end_test("md5 does not match"); + } + } + + system('kill -INT `cat t_foobar.pid`'); + + sleep(3); +} + +print "TEST PASSED\n"; + +sub generate_random_content { + my $size = shift; + my @chars=('a'..'z','A'..'Z','0'..'9'); + my $random_string = ''; + foreach (1..$size) { + $random_string.=$chars[rand @chars]; + } + + return $random_string; +} + +sub end_test { + my $msg = shift; + print 'TEST FAILED: '.$msg."\n"; + system('kill -INT `cat t_foobar.pid`'); + exit; +}