Ignore:
Timestamp:
2010-09-06T22:49:31+02:00 (6 years ago)
Author:
jow
Message:

[backfire] merge r22630, r22692, r22805

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/backfire/package/uhttpd/src/uhttpd-cgi.c

    r22590 r22962  
    136136 
    137137 
    138 void uh_cgi_request(struct client *cl, struct http_request *req, struct path_info *pi) 
    139 { 
    140         int i, hdroff, bufoff; 
     138void uh_cgi_request( 
     139        struct client *cl, struct http_request *req, 
     140        struct path_info *pi, struct interpreter *ip 
     141) { 
     142        int i, hdroff, bufoff, rv; 
    141143        int hdrlen = 0; 
    142144        int buflen = 0; 
     
    200202                        dup2(wfd[0], 0); 
    201203 
    202                         /* check for regular, world-executable file */ 
    203                         if( (pi->stat.st_mode & S_IFREG) && 
    204                             (pi->stat.st_mode & S_IXOTH) 
     204                        /* check for regular, world-executable file _or_ interpreter */ 
     205                        if( ((pi->stat.st_mode & S_IFREG) && 
     206                             (pi->stat.st_mode & S_IXOTH)) || (ip != NULL) 
    205207                        ) { 
    206208                                /* build environment */ 
     
    321323                                        perror("chdir()"); 
    322324 
    323                                 execl(pi->phys, pi->phys, NULL); 
     325                                if( ip != NULL ) 
     326                                        execl(ip->path, ip->path, pi->phys, NULL); 
     327                                else 
     328                                        execl(pi->phys, pi->phys, NULL); 
    324329 
    325330                                /* in case it fails ... */ 
     
    328333                                        "Unable to launch the requested CGI program:\n" 
    329334                                        "  %s: %s\n", 
    330                                                 pi->phys, strerror(errno) 
     335                                                ip ? ip->path : pi->phys, strerror(errno) 
    331336                                ); 
    332337                        } 
     
    372377                        memset(hdr, 0, sizeof(hdr)); 
    373378 
    374                         timeout.tv_sec = cl->server->conf->script_timeout; 
    375                         timeout.tv_usec = 0; 
    376  
    377 #define ensure(x) \ 
    378         do { if( x < 0 ) goto out; } while(0) 
    379  
    380379                        /* I/O loop, watch our pipe ends and dispatch child reads/writes from/to socket */ 
    381380                        while( 1 ) 
     
    387386                                FD_SET(wfd[1], &writer); 
    388387 
     388                                timeout.tv_sec = (header_sent < 1) ? cl->server->conf->script_timeout : 3; 
     389                                timeout.tv_usec = 0; 
     390 
     391                                ensure_out(rv = select_intr(fd_max, &reader, 
     392                                        (content_length > -1) ? &writer : NULL, NULL, &timeout)); 
     393 
     394                                /* timeout */ 
     395                                if( rv == 0 ) 
     396                                { 
     397                                        ensure_out(kill(child, 0)); 
     398                                } 
     399 
    389400                                /* wait until we can read or write or both */ 
    390                                 if( select_intr(fd_max, &reader, 
    391                                         (content_length > -1) ? &writer : NULL, NULL, 
    392                                         (header_sent < 1) ? &timeout : NULL) > 0 
    393                                 ) { 
     401                                else if( rv > 0 ) 
     402                                { 
    394403                                        /* ready to write to cgi program */ 
    395404                                        if( FD_ISSET(wfd[1], &writer) ) 
     
    399408                                                { 
    400409                                                        /* read it from socket ... */ 
    401                                                         if( (buflen = uh_tcp_recv(cl, buf, min(content_length, sizeof(buf)))) > 0 ) 
     410                                                        ensure_out(buflen = uh_tcp_recv(cl, buf, 
     411                                                                min(content_length, sizeof(buf)))); 
     412 
     413                                                        if( buflen > 0 ) 
    402414                                                        { 
    403415                                                                /* ... and write it to child's stdin */ 
     
    452464                                                                { 
    453465                                                                        /* write status */ 
    454                                                                         ensure(uh_http_sendf(cl, NULL, 
     466                                                                        ensure_out(uh_http_sendf(cl, NULL, 
    455467                                                                                "HTTP/%.1f %03d %s\r\n" 
    456468                                                                                "Connection: close\r\n", 
     
    462474                                                                            !uh_cgi_header_lookup(res, "Content-Type") 
    463475                                                                        ) { 
    464                                                                                 ensure(uh_http_send(cl, NULL, 
     476                                                                                ensure_out(uh_http_send(cl, NULL, 
    465477                                                                                        "Content-Type: text/plain\r\n", -1)); 
    466478                                                                        } 
     
    470482                                                                            !uh_cgi_header_lookup(res, "Transfer-Encoding") 
    471483                                                                        ) { 
    472                                                                                 ensure(uh_http_send(cl, NULL, 
     484                                                                                ensure_out(uh_http_send(cl, NULL, 
    473485                                                                                        "Transfer-Encoding: chunked\r\n", -1)); 
    474486                                                                        } 
     
    477489                                                                        foreach_header(i, res->headers) 
    478490                                                                        { 
    479                                                                                 ensure(uh_http_sendf(cl, NULL, "%s: %s\r\n", 
     491                                                                                ensure_out(uh_http_sendf(cl, NULL, "%s: %s\r\n", 
    480492                                                                                        res->headers[i], res->headers[i+1])); 
    481493                                                                        } 
    482494 
    483495                                                                        /* terminate header */ 
    484                                                                         ensure(uh_http_send(cl, NULL, "\r\n", -1)); 
     496                                                                        ensure_out(uh_http_send(cl, NULL, "\r\n", -1)); 
    485497 
    486498                                                                        /* push out remaining head buffer */ 
    487499                                                                        if( hdroff < hdrlen ) 
    488                                                                                 ensure(uh_http_send(cl, req, &hdr[hdroff], hdrlen - hdroff)); 
     500                                                                                ensure_out(uh_http_send(cl, req, &hdr[hdroff], hdrlen - hdroff)); 
    489501                                                                } 
    490502 
     
    492504                                                                else if( hdrlen >= sizeof(hdr) ) 
    493505                                                                { 
    494                                                                         ensure(uh_cgi_error_500(cl, req, 
     506                                                                        ensure_out(uh_cgi_error_500(cl, req, 
    495507                                                                                "The CGI program generated an invalid response:\n\n")); 
    496508 
    497                                                                         ensure(uh_http_send(cl, req, hdr, hdrlen)); 
     509                                                                        ensure_out(uh_http_send(cl, req, hdr, hdrlen)); 
    498510                                                                } 
    499511 
     
    506518                                                                /* push out remaining read buffer */ 
    507519                                                                if( bufoff < buflen ) 
    508                                                                         ensure(uh_http_send(cl, req, &buf[bufoff], buflen - bufoff)); 
     520                                                                        ensure_out(uh_http_send(cl, req, &buf[bufoff], buflen - bufoff)); 
    509521 
    510522                                                                header_sent = 1; 
     
    514526 
    515527                                                        /* headers complete, pass through buffer to socket */ 
    516                                                         ensure(uh_http_send(cl, req, buf, buflen)); 
     528                                                        ensure_out(uh_http_send(cl, req, buf, buflen)); 
    517529                                                } 
    518530 
     
    534546                                                                 */ 
    535547 
    536                                                                 ensure(uh_http_sendf(cl, NULL, 
     548                                                                ensure_out(uh_http_sendf(cl, NULL, 
    537549                                                                        "HTTP/%.1f 200 OK\r\n" 
    538550                                                                        "Content-Type: text/plain\r\n" 
     
    542554                                                                )); 
    543555 
    544                                                                 ensure(uh_http_send(cl, req, hdr, hdrlen)); 
     556                                                                ensure_out(uh_http_send(cl, req, hdr, hdrlen)); 
    545557                                                        } 
    546558 
    547559                                                        /* send final chunk if we're in chunked transfer mode */ 
    548                                                         ensure(uh_http_send(cl, req, "", 0)); 
     560                                                        ensure_out(uh_http_send(cl, req, "", 0)); 
    549561                                                        break; 
    550562                                                } 
     
    557569                                        if( (errno != EINTR) && ! header_sent ) 
    558570                                        { 
    559                                                 ensure(uh_http_sendhf(cl, 504, "Gateway Timeout", 
     571                                                ensure_out(uh_http_sendhf(cl, 504, "Gateway Timeout", 
    560572                                                        "The CGI script took too long to produce " 
    561573                                                        "a response")); 
     
    563575 
    564576                                        /* send final chunk if we're in chunked transfer mode */ 
    565                                         ensure(uh_http_send(cl, req, "", 0)); 
     577                                        ensure_out(uh_http_send(cl, req, "", 0)); 
    566578 
    567579                                        break; 
Note: See TracChangeset for help on using the changeset viewer.