Apache HTTPD
ajp_msg.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "ajp.h"
18
20
21#define AJP_MSG_DUMP_BYTES_PER_LINE 16
22/* 2 hex digits plus space plus one char per dumped byte */
23/* plus prefix plus separator plus '\0' */
24#define AJP_MSG_DUMP_PREFIX_LENGTH strlen("XXXX ")
25#define AJP_MSG_DUMP_LINE_LENGTH ((AJP_MSG_DUMP_BYTES_PER_LINE * \
26 strlen("XX .")) + \
27 AJP_MSG_DUMP_PREFIX_LENGTH + \
28 strlen(" - ") + 1)
29
30static char *hex_table = "0123456789ABCDEF";
31
43 apr_size_t count, char **buf)
44{
45 apr_size_t i, j;
46 char *current;
48 apr_byte_t x;
49 apr_size_t len = msg->len;
51
52 /* Display only first "count" bytes */
53 if (len > count)
54 len = count;
55 /* First the space needed for the first line */
56 bl = strlen(err) + 3 * (strlen(" XXX=") + 20) + 1 +
57 /* Now for the data lines */
58 (len + 15) / 16 * AJP_MSG_DUMP_LINE_LENGTH;
59 *buf = apr_palloc(pool, bl);
60 if (!*buf)
61 return APR_ENOMEM;
63 "%s pos=%" APR_SIZE_T_FMT
64 " len=%" APR_SIZE_T_FMT " max=%" APR_SIZE_T_FMT "\n",
65 err, msg->pos, msg->len, msg->max_size);
66 current = *buf + strlen(*buf);
67 for (i = 0; i < len; i += AJP_MSG_DUMP_BYTES_PER_LINE) {
68 /* Safety check: do we have enough buffer for another line? */
69 rl = bl - (current - *buf);
71 *(current - 1) = '\0';
72 return APR_ENOMEM;
73 }
74 apr_snprintf(current, rl, "%.4lx ", (unsigned long)i);
76 line_len = len - i;
79 }
80 for (j = 0; j < line_len; j++) {
81 x = msg->buf[i + j];
82
83 *current++ = hex_table[x >> 4];
84 *current++ = hex_table[x & 0x0f];
85 *current++ = ' ';
86 }
87 *current++ = ' ';
88 *current++ = '-';
89 *current++ = ' ';
90 for (j = 0; j < line_len; j++) {
91 x = msg->buf[i + j];
92
93 if (x > 0x20 && x < 0x7F) {
94 *current++ = x;
95 }
96 else {
97 *current++ = '.';
98 }
99 }
100 *current++ = '\n';
101 }
102 *(current - 1) = '\0';
103
104 return APR_SUCCESS;
105}
106
116{
117 int level;
119 char *buf, *next;
121
122 if (APLOGrtrace7(r)) {
123 level = APLOG_TRACE7;
124 count = 1024;
125 if (APLOGrtrace8(r)) {
126 level = APLOG_TRACE8;
128 }
129 rc = ajp_msg_dump(r->pool, msg, err, count, &buf);
130 if (rc == APR_SUCCESS) {
131 while ((next = ap_strchr(buf, '\n'))) {
132 *next = '\0';
133 /* Intentional no APLOGNO */
134 ap_log_rerror(APLOG_MARK, level, 0, r, "%s", buf);
135 buf = next + 1;
136 }
137 /* Intentional no APLOGNO */
138 ap_log_rerror(APLOG_MARK, level, 0, r, "%s", buf);
139 }
140 }
141 return rc;
142}
143
152{
153 apr_byte_t *head = msg->buf;
155
156 if (!((head[0] == 0x41 && head[1] == 0x42) ||
157 (head[0] == 0x12 && head[1] == 0x34))) {
158
160 "ajp_msg_check_header() got bad signature %02x%02x",
161 head[0], head[1]);
162
163 return AJP_EBAD_SIGNATURE;
164 }
165
166 msglen = ((head[2] & 0xff) << 8);
167 msglen += (head[3] & 0xFF);
168
169 if (msglen > msg->max_size) {
171 "ajp_msg_check_header() incoming message is "
172 "too big %" APR_SIZE_T_FMT ", max is %" APR_SIZE_T_FMT,
173 msglen, msg->max_size);
174 return AJP_ETOBIG;
175 }
176
177 msg->len = msglen + AJP_HEADER_LEN;
178 msg->pos = AJP_HEADER_LEN;
179 *len = msglen;
180
181 return APR_SUCCESS;
182}
183
191{
192 msg->len = AJP_HEADER_LEN;
193 msg->pos = AJP_HEADER_LEN;
194
195 return APR_SUCCESS;
196}
197
205{
207 apr_size_t max_size;
208
209 buf = msg->buf;
210 max_size = msg->max_size;
211 memset(msg, 0, sizeof(ajp_msg_t));
212 msg->buf = buf;
213 msg->max_size = max_size;
215 ajp_msg_reset(msg);
216 return APR_SUCCESS;
217}
218
226{
228
229 if (msg->server_side) {
230 msg->buf[0] = 0x41;
231 msg->buf[1] = 0x42;
232 }
233 else {
234 msg->buf[0] = 0x12;
235 msg->buf[1] = 0x34;
236 }
237
238 msg->buf[2] = (apr_byte_t)((len >> 8) & 0xFF);
239 msg->buf[3] = (apr_byte_t)(len & 0xFF);
240
241 return APR_SUCCESS;
242}
243
244static APR_INLINE int ajp_log_overflow(ajp_msg_t *msg, const char *context)
245{
247 "%s(): BufferOverflowException %" APR_SIZE_T_FMT
248 " %" APR_SIZE_T_FMT,
249 context, msg->pos, msg->len);
250 return AJP_EOVERFLOW;
251}
252
261{
262 apr_size_t len = msg->len;
263
264 if ((len + 4) > msg->max_size) {
265 return ajp_log_overflow(msg, "ajp_msg_append_uint32");
266 }
267
268 msg->buf[len] = (apr_byte_t)((value >> 24) & 0xFF);
269 msg->buf[len + 1] = (apr_byte_t)((value >> 16) & 0xFF);
270 msg->buf[len + 2] = (apr_byte_t)((value >> 8) & 0xFF);
271 msg->buf[len + 3] = (apr_byte_t)(value & 0xFF);
272
273 msg->len += 4;
274
275 return APR_SUCCESS;
276}
277
286{
287 apr_size_t len = msg->len;
288
289 if ((len + 2) > msg->max_size) {
290 return ajp_log_overflow(msg, "ajp_msg_append_uint16");
291 }
292
293 msg->buf[len] = (apr_byte_t)((value >> 8) & 0xFF);
294 msg->buf[len + 1] = (apr_byte_t)(value & 0xFF);
295
296 msg->len += 2;
297
298 return APR_SUCCESS;
299}
300
309{
310 apr_size_t len = msg->len;
311
312 if ((len + 1) > msg->max_size) {
313 return ajp_log_overflow(msg, "ajp_msg_append_uint8");
314 }
315
316 msg->buf[len] = value;
317 msg->len += 1;
318
319 return APR_SUCCESS;
320}
321
332 int convert)
333{
335
336 if (value == NULL) {
337 return(ajp_msg_append_uint16(msg, 0xFFFF));
338 }
339
340 len = strlen(value);
341 if ((msg->len + len + 3) > msg->max_size) {
342 return ajp_log_overflow(msg, "ajp_msg_append_cvt_string");
343 }
344
345 /* ignore error - we checked once */
347
348 /* We checked for space !! */
349 memcpy(msg->buf + msg->len, value, len + 1); /* including \0 */
350
351 if (convert) {
352 /* convert from EBCDIC if needed */
353 ap_xlate_proto_to_ascii((char *)msg->buf + msg->len, len + 1);
354 }
355
356 msg->len += len + 1;
357
358 return APR_SUCCESS;
359}
360
371{
372 if (! valuelen) {
373 return APR_SUCCESS; /* Shouldn't we indicate an error ? */
374 }
375
376 if ((msg->len + valuelen) > msg->max_size) {
377 return ajp_log_overflow(msg, "ajp_msg_append_bytes");
378 }
379
380 /* We checked for space !! */
381 memcpy(msg->buf + msg->len, value, valuelen);
382 msg->len += valuelen;
383
384 return APR_SUCCESS;
385}
386
395{
397
398 if ((msg->pos + 3) > msg->len) {
399 return ajp_log_overflow(msg, "ajp_msg_get_uint32");
400 }
401
402 value = ((msg->buf[(msg->pos++)] & 0xFF) << 24);
403 value |= ((msg->buf[(msg->pos++)] & 0xFF) << 16);
404 value |= ((msg->buf[(msg->pos++)] & 0xFF) << 8);
405 value |= ((msg->buf[(msg->pos++)] & 0xFF));
406
407 *rvalue = value;
408 return APR_SUCCESS;
409}
410
411
420{
422
423 if ((msg->pos + 1) > msg->len) {
424 return ajp_log_overflow(msg, "ajp_msg_get_uint16");
425 }
426
427 value = ((msg->buf[(msg->pos++)] & 0xFF) << 8);
428 value += ((msg->buf[(msg->pos++)] & 0xFF));
429
430 *rvalue = value;
431 return APR_SUCCESS;
432}
433
443{
445
446 if ((msg->pos + 1) > msg->len) {
447 return ajp_log_overflow(msg, "ajp_msg_peek_uint16");
448 }
449
450 value = ((msg->buf[(msg->pos)] & 0xFF) << 8);
451 value += ((msg->buf[(msg->pos + 1)] & 0xFF));
452
453 *rvalue = value;
454 return APR_SUCCESS;
455}
456
466{
467 if (msg->pos > msg->len) {
468 return ajp_log_overflow(msg, "ajp_msg_peek_uint8");
469 }
470
471 *rvalue = msg->buf[msg->pos];
472 return APR_SUCCESS;
473}
474
483{
484
485 if (msg->pos > msg->len) {
486 return ajp_log_overflow(msg, "ajp_msg_get_uint8");
487 }
488
489 *rvalue = msg->buf[msg->pos++];
490 return APR_SUCCESS;
491}
492
493
502{
506
508 start = msg->pos;
509
510 if ((status != APR_SUCCESS) || (size + start > msg->max_size)) {
511 return ajp_log_overflow(msg, "ajp_msg_get_string");
512 }
513
514 msg->pos += (apr_size_t)size;
515 msg->pos++; /* a String in AJP is NULL terminated */
516
517 *rvalue = (const char *)(msg->buf + start);
518 return APR_SUCCESS;
519}
520
521
532{
536
538 /* save the current position */
539 start = msg->pos;
540
541 if ((status != APR_SUCCESS) || (size + start > msg->max_size)) {
542 return ajp_log_overflow(msg, "ajp_msg_get_bytes");
543 }
544 msg->pos += (apr_size_t)size; /* only bytes, no trailer */
545
546 *rvalue = msg->buf + start;
547 *rvalue_len = size;
548
549 return APR_SUCCESS;
550}
551
552
562{
563 ajp_msg_t *msg = (ajp_msg_t *)apr_pcalloc(pool, sizeof(ajp_msg_t));
564
565 msg->server_side = 0;
566
567 msg->buf = (apr_byte_t *)apr_palloc(pool, size);
568 msg->len = 0;
570 msg->max_size = size;
571 *rmsg = msg;
572
573 return APR_SUCCESS;
574}
575
584{
585 if (smsg->len > smsg->max_size) {
587 "ajp_msg_copy(): destination buffer too "
588 "small %" APR_SIZE_T_FMT ", max size is %" APR_SIZE_T_FMT,
589 smsg->len, smsg->max_size);
590 return AJP_ETOSMALL;
591 }
592
593 memcpy(dmsg->buf, smsg->buf, smsg->len);
594 dmsg->len = smsg->len;
595 dmsg->pos = smsg->pos;
596
597 return APR_SUCCESS;
598}
599
600
612{
614 ajp_msg_reset(msg);
615
617 return rc;
618
619 return APR_SUCCESS;
620}
621
633{
635 ajp_msg_reset(msg);
636
638 return rc;
639
640 return APR_SUCCESS;
641}
Apache Jserv Protocol.
static APR_INLINE int ajp_log_overflow(ajp_msg_t *msg, const char *context)
Definition ajp_msg.c:244
static char * hex_table
Definition ajp_msg.c:30
#define AJP_MSG_DUMP_BYTES_PER_LINE
Definition ajp_msg.c:21
#define AJP_MSG_DUMP_PREFIX_LENGTH
Definition ajp_msg.c:24
#define AJP_MSG_DUMP_LINE_LENGTH
Definition ajp_msg.c:25
const char apr_size_t len
Definition ap_regex.h:187
apr_status_t ajp_msg_peek_uint8(ajp_msg_t *msg, apr_byte_t *rvalue)
Definition ajp_msg.c:465
apr_status_t ajp_msg_get_uint32(ajp_msg_t *msg, apr_uint32_t *rvalue)
Definition ajp_msg.c:394
apr_status_t ajp_msg_create(apr_pool_t *pool, apr_size_t size, ajp_msg_t **rmsg)
Definition ajp_msg.c:561
apr_status_t ajp_msg_append_uint8(ajp_msg_t *msg, apr_byte_t value)
Definition ajp_msg.c:308
apr_status_t ajp_msg_get_bytes(ajp_msg_t *msg, apr_byte_t **rvalue, apr_size_t *rvalue_len)
Definition ajp_msg.c:530
apr_status_t ajp_msg_dump(apr_pool_t *pool, ajp_msg_t *msg, char *err, apr_size_t count, char **buf)
Definition ajp_msg.c:42
apr_status_t ajp_msg_reuse(ajp_msg_t *msg)
Definition ajp_msg.c:204
apr_status_t ajp_msg_peek_uint16(ajp_msg_t *msg, apr_uint16_t *rvalue)
Definition ajp_msg.c:442
apr_status_t ajp_msg_check_header(ajp_msg_t *msg, apr_size_t *len)
Definition ajp_msg.c:151
apr_status_t ajp_msg_log(request_rec *r, ajp_msg_t *msg, char *err)
Definition ajp_msg.c:115
apr_status_t ajp_msg_get_string(ajp_msg_t *msg, const char **rvalue)
Definition ajp_msg.c:501
apr_status_t ajp_msg_serialize_ping(ajp_msg_t *msg)
Definition ajp_msg.c:611
apr_status_t ajp_msg_serialize_cping(ajp_msg_t *msg)
Definition ajp_msg.c:632
apr_status_t ajp_msg_append_uint32(ajp_msg_t *msg, apr_uint32_t value)
Definition ajp_msg.c:260
apr_status_t ajp_msg_get_uint8(ajp_msg_t *msg, apr_byte_t *rvalue)
Definition ajp_msg.c:482
apr_status_t ajp_msg_copy(ajp_msg_t *smsg, ajp_msg_t *dmsg)
Definition ajp_msg.c:583
apr_status_t ajp_msg_append_bytes(ajp_msg_t *msg, const apr_byte_t *value, apr_size_t valuelen)
Definition ajp_msg.c:369
apr_status_t ajp_msg_reset(ajp_msg_t *msg)
Definition ajp_msg.c:190
apr_status_t ajp_msg_append_uint16(ajp_msg_t *msg, apr_uint16_t value)
Definition ajp_msg.c:285
apr_status_t ajp_msg_end(ajp_msg_t *msg)
Definition ajp_msg.c:225
apr_status_t ajp_msg_get_uint16(ajp_msg_t *msg, apr_uint16_t *rvalue)
Definition ajp_msg.c:419
apr_status_t ajp_msg_append_string_ex(ajp_msg_t *msg, const char *value, int convert)
Definition ajp_msg.c:331
#define AJP_MAX_BUFFER_SZ
Definition ajp.h:136
#define AJP_ETOBIG
Definition ajp.h:95
#define AJP_HEADER_LEN
Definition ajp.h:132
#define CMD_AJP13_CPING
Definition ajp.h:157
#define AJP_ETOSMALL
Definition ajp.h:89
#define CMD_AJP13_PING
Definition ajp.h:153
#define AJP_EBAD_SIGNATURE
Definition ajp.h:93
#define AJP_EOVERFLOW
Definition ajp.h:87
#define APLOG_USE_MODULE(foo)
request_rec * r
#define ap_xlate_proto_to_ascii(x, y)
Definition util_ebcdic.h:80
#define APLOG_TRACE8
Definition http_log.h:79
#define APLOGNO(n)
Definition http_log.h:117
#define ap_log_rerror
Definition http_log.h:454
#define APLOG_ERR
Definition http_log.h:67
#define ap_log_error
Definition http_log.h:370
#define APLOG_MARK
Definition http_log.h:283
#define APLOGrtrace7(r)
Definition http_log.h:252
#define APLOG_TRACE7
Definition http_log.h:78
#define APLOGrtrace8(r)
Definition http_log.h:253
const unsigned char * buf
Definition util_md5.h:50
apr_md5_ctx_t * context
Definition util_md5.h:58
#define APR_ENOMEM
Definition apr_errno.h:683
unsigned int count
Definition apr_md5.h:152
apr_file_t apr_off_t start
apr_redis_t * rc
Definition apr_redis.h:173
#define ap_strchr(s, c)
Definition httpd.h:2351
apr_size_t size
const char int apr_pool_t * pool
Definition apr_cstr.h:84
const char * value
Definition apr_env.h:51
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
apr_int32_t apr_int32_t apr_int32_t err
int int status
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
Definition ajp.h:113
apr_size_t header_len
Definition ajp.h:117
apr_size_t max_size
Definition ajp.h:125
apr_byte_t * buf
Definition ajp.h:115
apr_size_t len
Definition ajp.h:119
int server_side
Definition ajp.h:123
apr_size_t pos
Definition ajp.h:121
A structure that represents the current request.
Definition httpd.h:845
apr_pool_t * pool
Definition httpd.h:847