You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Randy Terbush <ra...@zyzzyva.com> on 1997/07/06 07:43:44 UTC
Re: cvs commit: apache/src CHANGES alloc.c alloc.h http_protocol.c http_protocol.h mod_cgi.c util_script.c util_script.h
Uh, I would like to see some comments regarding this before it is
commited. Granted I did not veto it, but without some explanation,
I will. For one thing, it commits code that is commented out with
#if 0.
I raised several questions for which I saw no answer.
I would like to see us go back to the voting system for 1.3.
> sameer 97/07/05 22:37:24
>
> Modified: src CHANGES alloc.c alloc.h http_protocol.c
> http_protocol.h mod_cgi.c util_script.c
> util_script.h
> Log:
> Make cgi unbuffered so that nph is only a header thing
>
> Revision Changes Path
> 1.323 +2 -0 apache/src/CHANGES
>
> Index: CHANGES
> ===================================================================
> RCS file: /export/home/cvs/apache/src/CHANGES,v
> retrieving revision 1.322
> retrieving revision 1.323
> diff -c -C3 -r1.322 -r1.323
> *** CHANGES 1997/07/05 22:12:24 1.322
> --- CHANGES 1997/07/06 05:37:18 1.323
> ***************
> *** 1,4 ****
> --- 1,6 ----
> Changes with Apache 1.3
> + *) CGI: Add a select() loop so that CGI scripts don't have to be
> + nph in order to be "unbuffered". [Sameer Parekh]
>
> *) Makefile.nt added - to build all the bits from the command line:
> nmake -f Makefile.nt
>
>
>
> 1.36 +192 -0 apache/src/alloc.c
>
> Index: alloc.c
> ===================================================================
> RCS file: /export/home/cvs/apache/src/alloc.c,v
> retrieving revision 1.35
> retrieving revision 1.36
> diff -c -C3 -r1.35 -r1.36
> *** alloc.c 1997/06/29 19:19:34 1.35
> --- alloc.c 1997/07/06 05:37:18 1.36
> ***************
> *** 1025,1030 ****
> --- 1025,1222 ----
> #define enc_pipe(fds) pipe(fds)
> #endif /* WIN32 */
>
> +
> + int spawn_child_err_buff (pool *p, int (*func)(void *), void *data,
> + enum kill_conditions kill_how,
> + BUFF **pipe_in, BUFF **pipe_out, BUFF **pipe_err)
> + {
> + int pid;
> + int in_fds[2];
> + int out_fds[2];
> + int err_fds[2];
> + int save_errno;
> +
> + block_alarms();
> +
> + if (pipe_in && enc_pipe (in_fds) < 0)
> + {
> + save_errno = errno;
> + unblock_alarms();
> + errno = save_errno;
> + return 0;
> + }
> +
> + if (pipe_out && enc_pipe (out_fds) < 0) {
> + save_errno = errno;
> + if (pipe_in) {
> + close (in_fds[0]); close (in_fds[1]);
> + }
> + unblock_alarms();
> + errno = save_errno;
> + return 0;
> + }
> +
> + if (pipe_err && enc_pipe (err_fds) < 0) {
> + save_errno = errno;
> + if (pipe_in) {
> + close (in_fds[0]); close (in_fds[1]);
> + }
> + if (pipe_out) {
> + close (out_fds[0]); close (out_fds[1]);
> + }
> + unblock_alarms();
> + errno = save_errno;
> + return 0;
> + }
> +
> + #ifdef WIN32
> +
> + {
> + HANDLE thread_handle;
> + int hStdIn, hStdOut, hStdErr;
> + int old_priority;
> +
> + (void)acquire_mutex(spawn_mutex);
> + thread_handle = GetCurrentThread(); /* doesn't need to be closed */
> + old_priority = GetThreadPriority(thread_handle);
> + SetThreadPriority(thread_handle, THREAD_PRIORITY_HIGHEST);
> + /* Now do the right thing with your pipes */
> + if(pipe_in)
> + {
> + hStdIn = dup(fileno(stdin));
> + dup2(in_fds[0], fileno(stdin));
> + close(in_fds[0]);
> + }
> + if(pipe_out)
> + {
> + hStdOut = dup(fileno(stdout));
> + dup2(out_fds[1], fileno(stdout));
> + close(out_fds[1]);
> + }
> + if(pipe_err)
> + {
> + hStdErr = dup(fileno(stderr));
> + dup2(err_fds[1], fileno(stderr));
> + close(err_fds[1]);
> + }
> +
> + pid = (*func)(data);
> + if(!pid)
> + {
> + save_errno = errno;
> + close(in_fds[1]);
> + close(out_fds[0]);
> + close(err_fds[0]);
> + }
> +
> + /* restore the original stdin, stdout and stderr */
> + if(pipe_in)
> + dup2(hStdIn, fileno(stdin));
> + if(pipe_out)
> + dup2(hStdOut, fileno(stdout));
> + if(pipe_err)
> + dup2(hStdErr, fileno(stderr));
> +
> + if(pid)
> + {
> + note_subprocess(p, pid, kill_how);
> + if(pipe_in)
> + {
> + *pipe_in = bcreate(p, B_WR);
> + bpushfd(*pipe_in, in_fds[1], in_fds[1]);
> + }
> + if(pipe_out)
> + {
> + *pipe_out = bcreate(p, B_RD);
> + bpushfd(*pipe_out, out_fds[0], out_fds[0]);
> + }
> + if(pipe_err)
> + {
> + *pipe_err = bcreate(p, B_RD);
> + bpushfd(*pipe_err, err_fds[0], err_fds[0]);
> + }
> + }
> + SetThreadPriority(thread_handle, old_priority);
> + (void)release_mutex(spawn_mutex);
> + /*
> + * go on to the end of the function, where you can
> + * unblock alarms and return the pid
> + */
> +
> + }
> + #else
> +
> + if ((pid = fork()) < 0) {
> + save_errno = errno;
> + if (pipe_in) {
> + close (in_fds[0]); close (in_fds[1]);
> + }
> + if (pipe_out) {
> + close (out_fds[0]); close (out_fds[1]);
> + }
> + if (pipe_err) {
> + close (err_fds[0]); close (err_fds[1]);
> + }
> + unblock_alarms();
> + errno = save_errno;
> + return 0;
> + }
> +
> + if (!pid) {
> + /* Child process */
> +
> + if (pipe_out) {
> + close (out_fds[0]);
> + dup2 (out_fds[1], STDOUT_FILENO);
> + close (out_fds[1]);
> + }
> +
> + if (pipe_in) {
> + close (in_fds[1]);
> + dup2 (in_fds[0], STDIN_FILENO);
> + close (in_fds[0]);
> + }
> +
> + if (pipe_err) {
> + close (err_fds[0]);
> + dup2 (err_fds[1], STDERR_FILENO);
> + close (err_fds[1]);
> + }
> +
> + /* HP-UX SIGCHLD fix goes here, if someone will remind me what it is... */
> + signal (SIGCHLD, SIG_DFL); /* Was that it? */
> +
> + func (data);
> + exit (1); /* Should only get here if the exec in func() failed */
> + }
> +
> + /* Parent process */
> +
> + note_subprocess (p, pid, kill_how);
> +
> + if (pipe_out) {
> + close (out_fds[1]);
> + *pipe_out = bcreate(p, B_RD);
> + bpushfd(*pipe_out, out_fds[0], out_fds[0]);
> + }
> +
> + if (pipe_in) {
> + close (in_fds[0]);
> + *pipe_in = bcreate(p, B_WR);
> + bpushfd(*pipe_in, in_fds[1], in_fds[1]);
> + }
> +
> + if (pipe_err) {
> + close (err_fds[1]);
> + *pipe_err = bcreate(p, B_RD);
> + bpushfd(*pipe_err, err_fds[0], err_fds[0]);
> + }
> + #endif /* WIN32 */
> +
> + unblock_alarms();
> + return pid;
> + }
> +
> int spawn_child_err (pool *p, int (*func)(void *), void *data,
> enum kill_conditions kill_how,
> FILE **pipe_in, FILE **pipe_out, FILE **pipe_err)
>
>
>
> 1.24 +5 -0 apache/src/alloc.h
>
> Index: alloc.h
> ===================================================================
> RCS file: /export/home/cvs/apache/src/alloc.h,v
> retrieving revision 1.23
> retrieving revision 1.24
> diff -c -C3 -r1.23 -r1.24
> *** alloc.h 1997/06/28 20:24:27 1.23
> --- alloc.h 1997/07/06 05:37:19 1.24
> ***************
> *** 243,248 ****
> --- 243,253 ----
> int spawn_child_err (pool *, int (*)(void *), void *,
> enum kill_conditions, FILE **pipe_in, FILE **pipe_out,
> FILE **pipe_err);
> + #if 0
> + int spawn_child_err_buff (pool *, int (*)(void *), void *,
> + enum kill_conditions, BUFF **pipe_in, BUFF **pipe_out,
> + BUFF **pipe_err);
> + #endif
> #define spawn_child(p,f,v,k,in,out) spawn_child_err(p,f,v,k,in,out,NULL)
>
> /* magic numbers --- min free bytes to consider a free pool block useable,
>
>
>
> 1.133 +76 -0 apache/src/http_protocol.c
>
> Index: http_protocol.c
> ===================================================================
> RCS file: /export/home/cvs/apache/src/http_protocol.c,v
> retrieving revision 1.132
> retrieving revision 1.133
> diff -c -C3 -r1.132 -r1.133
> *** http_protocol.c 1997/07/05 14:53:57 1.132
> --- http_protocol.c 1997/07/06 05:37:19 1.133
> ***************
> *** 1516,1521 ****
> --- 1516,1597 ----
>
> return (chunk_start + len_read);
> }
> + long send_fb_length(BUFF *fb, request_rec *r, long length)
> + {
> + char buf[IOBUFSIZE];
> + long total_bytes_sent;
> + register int n, w, o;
> + conn_rec *c = r->connection;
> +
> + if (length == 0) return 0;
> +
> + total_bytes_sent = 0;
> +
> + /* Clear out the buffer */
> + if(fb->incnt != 0)
> + {
> + int o;
> + o = bwrite(c->client, fb->inptr, fb->incnt);
> + fb->incnt -= o;
> + fb->inptr += o;
> + total_bytes_sent += o;
> + }
> +
> + /* Make unbuffered */
> + fb->flags &= ~B_RD;
> +
> + while(1)
> + {
> + fd_set fds;
> +
> + bflush(c->client);
> +
> + FD_ZERO(&fds);
> + FD_SET(fb->fd_in, &fds);
> +
> + select(FD_SETSIZE, &fds, NULL, NULL, NULL);
> +
> + while((n = bread(fb, buf, IOBUFSIZE)) < 1
> + && fb->flags & B_ERROR && errno == EINTR)
> + continue;
> +
> + if (n < 1) {
> + break;
> + }
> + o=0;
> + total_bytes_sent += n;
> +
> + while (n && !r->connection->aborted) {
> + w = bwrite(r->connection->client, &buf[o], n);
> + if (w > 0) {
> + reset_timeout(r); /* reset timeout after successful write */
> + n-=w;
> + o+=w;
> + }
> + else if (w < 0) {
> + if (r->connection->aborted)
> + break;
> + else if (errno == EAGAIN)
> + continue;
> + else {
> + log_unixerr("send body lost connection to",
> + get_remote_host(r->connection,
> + r->per_dir_config, REMOTE_NAME),
> + NULL, r->server);
> + bsetflag(r->connection->client, B_EOUT, 1);
> + r->connection->aborted = 1;
> + break;
> + }
> + }
> + }
> + }
> +
> + kill_timeout(r);
> + SET_BYTES_SENT(r);
> + return total_bytes_sent;
> + }
> +
> + long send_fb(BUFF *fb, request_rec *r) { return send_fb_length(fb, r, -1); }
>
> long send_fd(FILE *f, request_rec *r) { return send_fd_length(f, r, -1); }
>
>
>
>
> 1.20 +3 -0 apache/src/http_protocol.h
>
> Index: http_protocol.h
> ===================================================================
> RCS file: /export/home/cvs/apache/src/http_protocol.h,v
> retrieving revision 1.19
> retrieving revision 1.20
> diff -c -C3 -r1.19 -r1.20
> *** http_protocol.h 1997/04/07 10:58:38 1.19
> --- http_protocol.h 1997/07/06 05:37:20 1.20
> ***************
> *** 110,115 ****
> --- 110,118 ----
>
> long send_fd(FILE *f, request_rec *r);
> long send_fd_length(FILE *f, request_rec *r, long length);
> +
> + long send_fb(BUFF *f, request_rec *r);
> + long send_fb_length(BUFF *f, request_rec *r, long length);
>
> /* Hmmm... could macrofy these for now, and maybe forever, though the
> * definitions of the macros would get a whole lot hairier.
>
>
>
> 1.43 +31 -47 apache/src/mod_cgi.c
>
> Index: mod_cgi.c
> ===================================================================
> RCS file: /export/home/cvs/apache/src/mod_cgi.c,v
> retrieving revision 1.42
> retrieving revision 1.43
> diff -c -C3 -r1.42 -r1.43
> *** mod_cgi.c 1997/06/29 17:39:50 1.42
> --- mod_cgi.c 1997/07/06 05:37:20 1.43
> ***************
> *** 183,189 ****
> }
>
> static int log_script(request_rec *r, cgi_server_conf *conf, int ret,
> ! char *dbuf, char *sbuf, FILE *script_in, FILE *script_err)
> {
> table *hdrs_arr = r->headers_in;
> table_entry *hdrs = (table_entry *)hdrs_arr->elts;
> --- 183,189 ----
> }
>
> static int log_script(request_rec *r, cgi_server_conf *conf, int ret,
> ! char *dbuf, char *sbuf, BUFF *script_in, BUFF *script_err)
> {
> table *hdrs_arr = r->headers_in;
> table_entry *hdrs = (table_entry *)hdrs_arr->elts;
> ***************
> *** 197,205 ****
> ((f = pfopen(r->pool, server_root_relative(r->pool, conf->logname),
> "a")) == NULL)) {
> /* Soak up script output */
> ! while (fgets(argsbuffer, MAX_STRING_LEN-1, script_in) != NULL)
> continue;
> ! while (fgets(argsbuffer, MAX_STRING_LEN-1, script_err) != NULL)
> continue;
> return ret;
> }
> --- 197,205 ----
> ((f = pfopen(r->pool, server_root_relative(r->pool, conf->logname),
> "a")) == NULL)) {
> /* Soak up script output */
> ! while (bgets(argsbuffer, MAX_STRING_LEN-1, script_in))
> continue;
> ! while (bgets(argsbuffer, MAX_STRING_LEN-1, script_err))
> continue;
> return ret;
> }
> ***************
> *** 207,213 ****
> /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */
> fprintf(f, "%%%% [%s] %s %s%s%s %s\n", get_time(), r->method, r->uri,
> r->args ? "?" : "", r->args ? r->args : "", r->protocol);
> ! /* "%% 500 /usr/local/etc/httpd/cgi-bin */
> fprintf(f, "%%%% %d %s\n", ret, r->filename);
>
> fputs("%request\n", f);
> --- 207,213 ----
> /* "%% [Wed Jun 19 10:53:21 1996] GET /cgi-bin/printenv HTTP/1.0" */
> fprintf(f, "%%%% [%s] %s %s%s%s %s\n", get_time(), r->method, r->uri,
> r->args ? "?" : "", r->args ? r->args : "", r->protocol);
> ! /* "%% 500 /usr/local/etc/httpd/cgi-bin" */
> fprintf(f, "%%%% %d %s\n", ret, r->filename);
>
> fputs("%request\n", f);
> ***************
> *** 216,222 ****
> fprintf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val);
> }
> if ((r->method_number == M_POST || r->method_number == M_PUT)
> ! && dbuf && *dbuf) {
> fprintf(f, "\n%s\n", dbuf);
> }
>
> --- 216,222 ----
> fprintf(f, "%s: %s\n", hdrs[i].key, hdrs[i].val);
> }
> if ((r->method_number == M_POST || r->method_number == M_PUT)
> ! && *dbuf) {
> fprintf(f, "\n%s\n", dbuf);
> }
>
> ***************
> *** 233,259 ****
> fprintf(f, "%s\n", sbuf);
>
> *argsbuffer = '\0';
> ! fgets(argsbuffer, HUGE_STRING_LEN-1, script_in);
> if (*argsbuffer) {
> fputs("%stdout\n", f);
> fputs(argsbuffer, f);
> ! while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_in) != NULL)
> fputs(argsbuffer, f);
> fputs("\n", f);
> }
>
> *argsbuffer = '\0';
> ! fgets(argsbuffer, HUGE_STRING_LEN-1, script_err);
> if (*argsbuffer) {
> fputs("%stderr\n", f);
> fputs(argsbuffer, f);
> ! while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_err) != NULL)
> fputs(argsbuffer, f);
> fputs("\n", f);
> }
>
> ! pfclose(r->main ? r->main->pool : r->pool, script_in);
> ! pfclose(r->main ? r->main->pool : r->pool, script_err);
>
> pfclose(r->pool, f);
> return ret;
> --- 233,259 ----
> fprintf(f, "%s\n", sbuf);
>
> *argsbuffer = '\0';
> ! bgets(argsbuffer, HUGE_STRING_LEN-1, script_in);
> if (*argsbuffer) {
> fputs("%stdout\n", f);
> fputs(argsbuffer, f);
> ! while (bgets(argsbuffer, HUGE_STRING_LEN-1, script_in))
> fputs(argsbuffer, f);
> fputs("\n", f);
> }
>
> *argsbuffer = '\0';
> ! bgets(argsbuffer, HUGE_STRING_LEN-1, script_err);
> if (*argsbuffer) {
> fputs("%stderr\n", f);
> fputs(argsbuffer, f);
> ! while (bgets(argsbuffer, HUGE_STRING_LEN-1, script_err))
> fputs(argsbuffer, f);
> fputs("\n", f);
> }
>
> ! bclose(script_in);
> ! bclose(script_err);
>
> pfclose(r->pool, f);
> return ret;
> ***************
> *** 277,283 ****
> struct cgi_child_stuff *cld = (struct cgi_child_stuff *)child_stuff;
> request_rec *r = cld->r;
> char *argv0 = cld->argv0;
> - int nph = cld->nph;
> int child_pid;
>
> #ifdef DEBUG_CGI
> --- 277,282 ----
> ***************
> *** 312,321 ****
> if (!cld->debug)
> error_log2stderr (r->server);
>
> - #if !defined(__EMX__) && !defined(WIN32)
> - if (nph) client_to_stdout (r->connection);
> - #endif
> -
> /* Transumute outselves into the script.
> * NB only ISINDEX scripts get decoded arguments.
> */
> --- 311,316 ----
> ***************
> *** 352,358 ****
> {
> int retval, nph, dbpos = 0;
> char *argv0, *dbuf = NULL;
> ! FILE *script_out, *script_in, *script_err;
> char argsbuffer[HUGE_STRING_LEN];
> int is_included = !strcmp (r->protocol, "INCLUDED");
> void *sconf = r->server->module_config;
> --- 347,353 ----
> {
> int retval, nph, dbpos = 0;
> char *argv0, *dbuf = NULL;
> ! BUFF *script_out, *script_in, *script_err;
> char argsbuffer[HUGE_STRING_LEN];
> int is_included = !strcmp (r->protocol, "INCLUDED");
> void *sconf = r->server->module_config;
> ***************
> *** 421,435 ****
> * waiting for free_proc_chain to cleanup in the middle of an
> * SSI request -djg
> */
> ! spawn_child_err (r->main ? r->main->pool : r->pool, cgi_child,
> ! (void *)&cld,
> ! nph ? just_wait : kill_after_timeout,
> ! #if defined(__EMX__) || defined(WIN32)
> ! &script_out, &script_in, &script_err))) {
> ! #else
> ! &script_out, nph ? NULL : &script_in,
> ! &script_err))) {
> ! #endif
> log_reason ("couldn't spawn child process", r->filename, r);
> return SERVER_ERROR;
> }
> --- 416,425 ----
> * waiting for free_proc_chain to cleanup in the middle of an
> * SSI request -djg
> */
> ! spawn_child_err_buff (r->main ? r->main->pool : r->pool, cgi_child,
> ! (void *)&cld,
> ! kill_after_timeout,
> ! &script_out, &script_in, &script_err))) {
> log_reason ("couldn't spawn child process", r->filename, r);
> return SERVER_ERROR;
> }
> ***************
> *** 471,477 ****
> dbpos += dbsize;
> }
> reset_timeout(r);
> ! if (fwrite(argsbuffer, sizeof(char), len_read, script_out)
> < (size_t)len_read) {
> /* silly script stopped reading, soak up remaining message */
> while (get_client_block(r, argsbuffer, HUGE_STRING_LEN) > 0)
> --- 461,467 ----
> dbpos += dbsize;
> }
> reset_timeout(r);
> ! if (bwrite(script_out, argsbuffer, len_read)
> < (size_t)len_read) {
> /* silly script stopped reading, soak up remaining message */
> while (get_client_block(r, argsbuffer, HUGE_STRING_LEN) > 0)
> ***************
> *** 480,499 ****
> }
> }
>
> ! fflush (script_out);
> signal (SIGPIPE, handler);
>
> kill_timeout (r);
> }
>
> ! pfclose (r->main ? r->main->pool : r->pool, script_out);
>
> /* Handle script return... */
> if (script_in && !nph) {
> char *location, sbuf[MAX_STRING_LEN];
> int ret;
>
> ! if ((ret = scan_script_header_err(r, script_in, sbuf)))
> return log_script(r, conf, ret, dbuf, sbuf, script_in, script_err);
>
> location = table_get (r->headers_out, "Location");
> --- 470,489 ----
> }
> }
>
> ! bflush (script_out);
> signal (SIGPIPE, handler);
>
> kill_timeout (r);
> }
>
> ! bclose(script_out);
>
> /* Handle script return... */
> if (script_in && !nph) {
> char *location, sbuf[MAX_STRING_LEN];
> int ret;
>
> ! if ((ret = scan_script_header_err_buff(r, script_in, sbuf)))
> return log_script(r, conf, ret, dbuf, sbuf, script_in, script_err);
>
> location = table_get (r->headers_out, "Location");
> ***************
> *** 502,512 ****
>
> /* Soak up all the script output */
> hard_timeout ("read from script", r);
> ! while (fread(argsbuffer, sizeof(char), HUGE_STRING_LEN, script_in)
> ! > 0)
> continue;
> ! while (fread(argsbuffer, sizeof(char), HUGE_STRING_LEN, script_err)
> ! > 0)
> continue;
> kill_timeout (r);
>
> --- 492,500 ----
>
> /* Soak up all the script output */
> hard_timeout ("read from script", r);
> ! while (bgets(argsbuffer, HUGE_STRING_LEN-1, script_in))
> continue;
> ! while (bgets(argsbuffer, HUGE_STRING_LEN-1, script_err))
> continue;
> kill_timeout (r);
>
> ***************
> *** 535,558 ****
>
> send_http_header(r);
> if (!r->header_only)
> ! send_fd(script_in, r);
> ! pfclose (r->main ? r->main->pool : r->pool, script_in);
>
> - /* Soak up stderr */
> soft_timeout("soaking script stderr", r);
> ! while (!r->connection->aborted &&
> ! (fread(argsbuffer, sizeof(char), HUGE_STRING_LEN, script_err) > 0))
> ! continue;
> kill_timeout(r);
> ! pfclose (r->main ? r->main->pool : r->pool, script_err);
> }
>
> ! if (nph) {
> ! #if defined(__EMX__) || defined(WIN32)
> ! while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_in) != NULL) {
> ! bputs(argsbuffer, r->connection->client);
> ! }
> ! #else
> waitpid(child_pid, (int*)0, 0);
> #endif
> }
> --- 523,542 ----
>
> send_http_header(r);
> if (!r->header_only)
> ! send_fb(script_in, r);
>
> soft_timeout("soaking script stderr", r);
> ! while(bgets(argsbuffer, HUGE_STRING_LEN-1, script_err))
> ! continue;
> kill_timeout(r);
> !
> ! bclose(script_in);
> ! bclose(script_out);
> }
>
> ! if (script_in && nph) {
> ! send_fb(script_in, r);
> ! #if !defined(__EMX__) && !defined(WIN32)
> waitpid(child_pid, (int*)0, 0);
> #endif
> }
>
>
>
> 1.63 +89 -0 apache/src/util_script.c
>
> Index: util_script.c
> ===================================================================
> RCS file: /export/home/cvs/apache/src/util_script.c,v
> retrieving revision 1.62
> retrieving revision 1.63
> diff -c -C3 -r1.62 -r1.63
> *** util_script.c 1997/06/29 19:19:37 1.62
> --- util_script.c 1997/07/06 05:37:20 1.63
> ***************
> *** 312,317 ****
> --- 312,406 ----
> }
> }
>
> + int scan_script_header_err_buff(request_rec *r, BUFF *fb, char *buffer)
> + {
> + char x[MAX_STRING_LEN];
> + char *w, *l;
> + int p;
> +
> + if (buffer) *buffer = '\0';
> + w = buffer ? buffer : x;
> +
> + hard_timeout ("read script header", r);
> +
> + while(1) {
> +
> + if (bgets(w, MAX_STRING_LEN-1, fb) <= 0) {
> + log_reason ("Premature end of script headers", r->filename, r);
> + return SERVER_ERROR;
> + }
> +
> + /* Delete terminal (CR?)LF */
> +
> + p = strlen(w);
> + if (p > 0 && w[p-1] == '\n')
> + {
> + if (p > 1 && w[p-2] == '\015') w[p-2] = '\0';
> + else w[p-1] = '\0';
> + }
> +
> + if(w[0] == '\0') {
> + kill_timeout (r);
> + return OK;
> + }
> +
> + /* if we see a bogus header don't ignore it. Shout and scream */
> +
> + if(!(l = strchr(w,':'))) {
> + char malformed[(sizeof MALFORMED_MESSAGE)+1+MALFORMED_HEADER_LENGTH_TO_SHOW];
> + strcpy(malformed, MALFORMED_MESSAGE);
> + strncat(malformed, w, MALFORMED_HEADER_LENGTH_TO_SHOW);
> +
> + if (!buffer)
> + /* Soak up all the script output --- may save an outright kill */
> + while (bgets(w, MAX_STRING_LEN-1, fb) <= 0)
> + continue;
> +
> + kill_timeout (r);
> + log_reason (malformed, r->filename, r);
> + return SERVER_ERROR;
> + }
> +
> + *l++ = '\0';
> + while (*l && isspace (*l)) ++l;
> +
> + if(!strcasecmp(w,"Content-type")) {
> +
> + /* Nuke trailing whitespace */
> +
> + char *endp = l + strlen(l) - 1;
> + while (endp > l && isspace(*endp)) *endp-- = '\0';
> +
> + r->content_type = pstrdup (r->pool, l);
> + }
> + else if(!strcasecmp(w,"Status")) {
> + sscanf(l, "%d", &r->status);
> + r->status_line = pstrdup(r->pool, l);
> + }
> + else if(!strcasecmp(w,"Location")) {
> + table_set (r->headers_out, w, l);
> + }
> + else if(!strcasecmp(w,"Content-Length")) {
> + table_set (r->headers_out, w, l);
> + }
> + else if(!strcasecmp(w,"Transfer-Encoding")) {
> + table_set (r->headers_out, w, l);
> + }
> +
> + /* The HTTP specification says that it is legal to merge duplicate
> + * headers into one. Some browsers that support Cookies don't like
> + * merged headers and prefer that each Set-Cookie header is sent
> + * separately. Lets humour those browsers.
> + */
> + else if(!strcasecmp(w, "Set-Cookie")) {
> + table_add(r->err_headers_out, w, l);
> + }
> + else {
> + table_merge (r->err_headers_out, w, l);
> + }
> + }
> + }
> +
> int scan_script_header_err(request_rec *r, FILE *f, char *buffer)
> {
> char x[MAX_STRING_LEN];
>
>
>
> 1.18 +1 -0 apache/src/util_script.h
>
> Index: util_script.h
> ===================================================================
> RCS file: /export/home/cvs/apache/src/util_script.h,v
> retrieving revision 1.17
> retrieving revision 1.18
> diff -c -C3 -r1.17 -r1.18
> *** util_script.h 1997/06/15 19:22:35 1.17
> --- util_script.h 1997/07/06 05:37:20 1.18
> ***************
> *** 64,69 ****
> --- 64,70 ----
> void add_common_vars(request_rec *r);
> #define scan_script_header(a1,a2) scan_script_header_err(a1,a2,NULL)
> int scan_script_header_err(request_rec *r, FILE *f, char *buffer);
> + int scan_script_header_err_buff(request_rec *r, BUFF *f, char *buffer);
> void send_size(size_t size, request_rec *r);
> int call_exec (request_rec *r, char *argv0, char **env, int shellcmd);
>
>
>
>