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 19 20apr_status_t ajp_ilink_send(apr_socket_t *sock, ajp_msg_t *msg) 21{ 22 char *buf; 23 apr_status_t status; 24 apr_size_t length; 25 26 if (sock == NULL) { 27 ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, 28 "ajp_ilink_send(): NULL socket provided"); 29 return AJP_EINVAL; 30 } 31 32 ajp_msg_end(msg); 33 34 length = msg->len; 35 buf = (char *)msg->buf; 36 37 do { 38 apr_size_t written = length; 39 40 status = apr_socket_send(sock, buf, &written); 41 if (status != APR_SUCCESS) { 42 ap_log_error(APLOG_MARK, APLOG_ERR, status, NULL, 43 "ajp_ilink_send(): send failed"); 44 return status; 45 } 46 length -= written; 47 buf += written; 48 } while (length); 49 50 return APR_SUCCESS; 51} 52 53 54static apr_status_t ilink_read(apr_socket_t *sock, apr_byte_t *buf, 55 apr_size_t len) 56{ 57 apr_size_t length = len; 58 apr_size_t rdlen = 0; 59 apr_status_t status; 60 61 while (rdlen < len) { 62 63 status = apr_socket_recv(sock, (char *)(buf + rdlen), &length); 64 65 if (status == APR_EOF) 66 return status; /* socket closed. */ 67 else if (APR_STATUS_IS_EAGAIN(status)) 68 continue; 69 else if (status != APR_SUCCESS) 70 return status; /* any error. */ 71 72 rdlen += length; 73 length = len - rdlen; 74 } 75 return APR_SUCCESS; 76} 77 78 79apr_status_t ajp_ilink_receive(apr_socket_t *sock, ajp_msg_t *msg) 80{ 81 apr_status_t status; 82 apr_size_t hlen; 83 apr_size_t blen; 84 85 if (sock == NULL) { 86 ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, 87 "ajp_ilink_receive(): NULL socket provided"); 88 return AJP_EINVAL; 89 } 90 91 hlen = msg->header_len; 92 93 status = ilink_read(sock, msg->buf, hlen); 94 95 if (status != APR_SUCCESS) { 96 ap_log_error(APLOG_MARK, APLOG_ERR, status, NULL, 97 "ajp_ilink_receive() can't receive header"); 98 return (APR_STATUS_IS_TIMEUP(status) ? APR_TIMEUP : AJP_ENO_HEADER); 99 } 100 101 status = ajp_msg_check_header(msg, &blen); 102 103 if (status != APR_SUCCESS) { 104 ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, 105 "ajp_ilink_receive() received bad header"); 106 return AJP_EBAD_HEADER; 107 } 108 109 status = ilink_read(sock, msg->buf + hlen, blen); 110 111 if (status != APR_SUCCESS) { 112 ap_log_error(APLOG_MARK, APLOG_ERR, status, NULL, 113 "ajp_ilink_receive() error while receiving message body " 114 "of length %" APR_SIZE_T_FMT, 115 hlen); 116 return AJP_EBAD_MESSAGE; 117 } 118 119 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, 120 "ajp_ilink_receive() received packet len=%" APR_SIZE_T_FMT 121 "type=%d", 122 blen, (int)msg->buf[hlen]); 123 124 return APR_SUCCESS; 125} 126 127