View | Details | Raw Unified | Return to bug 61909
Collapse All | Expand All

(-)fcgid_bucket.c.1527362 (-35 / +80 lines)
Lines 20-25 Link Here
20
#include "fcgid_bridge.h"
20
#include "fcgid_bridge.h"
21
21
22
#define FCGID_FEED_LEN 8192
22
#define FCGID_FEED_LEN 8192
23
/* fcgid_feed_data reads up to 8k from the fastcgi process into 
24
 * a heap bucket */
23
static apr_status_t fcgid_feed_data(fcgid_bucket_ctx * ctx,
25
static apr_status_t fcgid_feed_data(fcgid_bucket_ctx * ctx,
24
                                    apr_bucket_alloc_t * bucketalloc,
26
                                    apr_bucket_alloc_t * bucketalloc,
25
                                    char **buffer, apr_size_t * bufferlen)
27
                                    char **buffer, apr_size_t * bufferlen)
Lines 43-49 Link Here
43
                                   apr_bucket_free, bucketalloc);
45
                                   apr_bucket_free, bucketalloc);
44
        if (*bufferlen != FCGID_FEED_LEN) {
46
        if (*bufferlen != FCGID_FEED_LEN) {
45
            apr_bucket *buckettmp;
47
            apr_bucket *buckettmp;
46
48
            /* not all of the newly created bucket was used, so 
49
             * split the bucket and remove the remainder */
47
            apr_bucket_split(ctx->buffer, *bufferlen);
50
            apr_bucket_split(ctx->buffer, *bufferlen);
48
            buckettmp = APR_BUCKET_NEXT(ctx->buffer);
51
            buckettmp = APR_BUCKET_NEXT(ctx->buffer);
49
            apr_bucket_delete(buckettmp);
52
            apr_bucket_delete(buckettmp);
Lines 112-161 Link Here
112
    if (header.type == FCGI_STDERR) {
115
    if (header.type == FCGI_STDERR) {
113
        char *logbuf = apr_bucket_alloc(APR_BUCKET_BUFF_SIZE, b->list);
116
        char *logbuf = apr_bucket_alloc(APR_BUCKET_BUFF_SIZE, b->list);
114
        char *line;
117
        char *line;
115
        apr_size_t hasput;
118
        apr_size_t hasputbuf;
116
119
120
        /* 0-pad the logbuf */
117
        memset(logbuf, 0, APR_BUCKET_BUFF_SIZE);
121
        memset(logbuf, 0, APR_BUCKET_BUFF_SIZE);
118
122
119
        hasread = 0;
123
        hasread = 0;
120
        hasput = 0;
124
        hasputbuf = 0;
121
        while (hasread < bodysize) {
125
        while (hasread < bodysize) {
122
            char *buffer;
126
            char *buffer;
123
            apr_size_t bufferlen, canput, willput;
124
127
125
            /* Feed some data if necessary */
128
            while (hasread < bodysize 
126
            if ((rv =
129
                   && hasputbuf < (APR_BUCKET_BUFF_SIZE-1)) {
127
                 fcgid_feed_data(ctx, b->list, &buffer,
130
                apr_size_t bufferlen, canput, willput;
128
                                 &bufferlen)) != APR_SUCCESS) {
131
129
                apr_bucket_free(logbuf);
132
                /* Feed some data if necessary */
130
                return rv;
133
                if ((rv =
134
                     fcgid_feed_data(ctx, b->list, &buffer,
135
                                     &bufferlen)) != APR_SUCCESS) {
136
                    apr_bucket_free(logbuf);
137
                    return rv;
138
                }
139
140
                /* canput is how much data is available for reading,
141
                 * either the remaining body size or the max buffer size. 
142
                 * This because we can read more than the bodysize 
143
                 * (the nex factcgi packet) */
144
                canput = fcgid_min(bufferlen, bodysize - hasread);
145
                /* willput is what we will actually write to the 
146
                 * buffer (which is limited by buffer size) the 
147
                 * remaining data will stay in the bucket */
148
                willput = fcgid_min(canput, 
149
                                    APR_BUCKET_BUFF_SIZE - hasputbuf - 1);
150
                memcpy(logbuf + hasputbuf, buffer, willput);
151
                hasread += willput;
152
                hasputbuf += willput;
153
                
154
                /* Ignore the "willput" bytes */
155
                fcgid_ignore_bytes(ctx, willput);
131
            }
156
            }
132
157
133
            canput = fcgid_min(bufferlen, bodysize - hasread);
158
            /* Now I get the log data, write log and release the buffer */
134
            willput =
159
            line = logbuf;
135
                fcgid_min(canput, APR_BUCKET_BUFF_SIZE - hasput - 1);
160
            while (*line) {
136
            memcpy(logbuf + hasput, buffer, willput);
161
                /* find the first occurence of \r or \n */
137
            hasread += canput;
162
                char *end = strpbrk(line, "\r\n");
138
            hasput += willput;
163
                /* and replace by string terminator */
139
164
                if (end != NULL) {
140
            /* Ignore the "canput" bytes */
165
                    *end = '\0';
141
            fcgid_ignore_bytes(ctx, canput);
166
                } else {
142
        }
167
                    /* did not detect anymore newlines */
143
168
                    if(line != logbuf && hasread < bodysize){
144
        /* Now I get the log data, write log and release the buffer */
169
                        /* if not yet done with the body because buffer was 
145
        line = logbuf;
170
                         * full AND we did detect at least one linebreak
146
        while (*line) {
171
                         * then we try to get more STDERR data so we won't
147
            char *end = strpbrk(line, "\r\n");
172
                         * break up errorlines unnessesary */
148
173
                        hasputbuf = strlen(line);
149
            if (end != NULL) {
174
                        memmove(logbuf, line, hasputbuf);
150
                *end = '\0';
175
                        memset(logbuf + hasputbuf, 0,
151
            }
176
                               APR_BUCKET_BUFF_SIZE - hasputbuf);
152
            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, ctx->ipc.request,
177
                        break;
153
                          "mod_fcgid: stderr: %s", line);
178
                    }
154
            if (end == NULL) {
179
                }
155
                break;
180
                ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, ctx->ipc.request,
181
                              "mod_fcgid: stderr: %s", line);
182
                /* if we did not find \r or \n then we're done 
183
                 * (we hit the end of the logbuf) */
184
                if (end == NULL) {
185
                    /* 0-pad the logbuf */
186
                    memset(logbuf, 0, APR_BUCKET_BUFF_SIZE);
187
                    hasputbuf = 0;
188
                    break;
189
                }
190
                /* skip past our inserted string terminator */
191
                ++end;
192
                /* and skip all \r or \n characters at the beginning 
193
                 * of the next part of logbuf */
194
                line = end + strspn(end, "\r\n");
195
                if(!*line && hasread < bodysize){
196
                    /* okay, our logbuf ends with a newline but we still 
197
                     * need to process some more data. This is an edge 
198
                     * case but we need to clear the logbuf. */
199
                    memset(logbuf, 0, APR_BUCKET_BUFF_SIZE);
200
                    hasputbuf = 0;
201
                }
156
            }
202
            }
157
            ++end;
203
158
            line = end + strspn(end, "\r\n");
159
        }
204
        }
160
205
161
        apr_bucket_free(logbuf);
206
        apr_bucket_free(logbuf);

Return to bug 61909