///////////////////////////////////////////////////////////////////////// void HttpTransact::build_error_response( State *s, HTTPStatus status_code, char *reason_phrase_or_null, char *error_body_type, char *format, ...) This method sets the requires state for an error reply, including the error text, status code, reason phrase, and reply headers. The caller calls the method with the HttpTransac
| 8022 | // |
| 8023 | ////////////////////////////////////////////////////////////////////////////// |
| 8024 | void |
| 8025 | HttpTransact::build_error_response(State *s, HTTPStatus status_code, const char *reason_phrase_or_null, const char *error_body_type) |
| 8026 | { |
| 8027 | char body_language[256], body_type[256]; |
| 8028 | |
| 8029 | if (nullptr == error_body_type) { |
| 8030 | error_body_type = "default"; |
| 8031 | } |
| 8032 | |
| 8033 | // Make sure that if this error occurred before we initialized the state variables that we do now. |
| 8034 | initialize_state_variables_from_request(s, &s->hdr_info.client_request); |
| 8035 | |
| 8036 | ////////////////////////////////////////////////////// |
| 8037 | // If there is a request body, we must disable // |
| 8038 | // keep-alive to prevent the body being read as // |
| 8039 | // the next header (unless we've already drained // |
| 8040 | // which we do for NTLM auth) // |
| 8041 | ////////////////////////////////////////////////////// |
| 8042 | if (status_code == HTTP_STATUS_REQUEST_TIMEOUT || s->hdr_info.client_request.get_content_length() != 0 || |
| 8043 | s->client_info.transfer_encoding == HttpTransact::CHUNKED_ENCODING) { |
| 8044 | s->client_info.keep_alive = HTTP_NO_KEEPALIVE; |
| 8045 | } else { |
| 8046 | // We don't have a request body. Since we are |
| 8047 | // generating the error, we know we can trust |
| 8048 | // the content-length |
| 8049 | s->hdr_info.trust_response_cl = true; |
| 8050 | } |
| 8051 | // If transparent and the forward server connection looks unhappy don't |
| 8052 | // keep alive the ua connection. |
| 8053 | if ((s->state_machine->get_ua_txn() && s->state_machine->get_ua_txn()->is_outbound_transparent()) && |
| 8054 | (status_code == HTTP_STATUS_INTERNAL_SERVER_ERROR || status_code == HTTP_STATUS_GATEWAY_TIMEOUT || |
| 8055 | status_code == HTTP_STATUS_BAD_GATEWAY || status_code == HTTP_STATUS_SERVICE_UNAVAILABLE)) { |
| 8056 | s->client_info.keep_alive = HTTP_NO_KEEPALIVE; |
| 8057 | } |
| 8058 | |
| 8059 | // If there is a parse error on reading the request it can leave reading the request stream in an undetermined state |
| 8060 | if (status_code == HTTP_STATUS_BAD_REQUEST) { |
| 8061 | s->client_info.keep_alive = HTTP_NO_KEEPALIVE; |
| 8062 | } |
| 8063 | |
| 8064 | switch (status_code) { |
| 8065 | case HTTP_STATUS_BAD_REQUEST: |
| 8066 | SET_VIA_STRING(VIA_CLIENT_REQUEST, VIA_CLIENT_ERROR); |
| 8067 | // Did the via error already get set by the loop detection |
| 8068 | if (s->via_string[VIA_ERROR_TYPE] != VIA_ERROR_LOOP_DETECTED) { |
| 8069 | SET_VIA_STRING(VIA_ERROR_TYPE, VIA_ERROR_HEADER_SYNTAX); |
| 8070 | } |
| 8071 | break; |
| 8072 | case HTTP_STATUS_BAD_GATEWAY: |
| 8073 | SET_VIA_STRING(VIA_ERROR_TYPE, VIA_ERROR_CONNECTION); |
| 8074 | break; |
| 8075 | case HTTP_STATUS_GATEWAY_TIMEOUT: |
| 8076 | SET_VIA_STRING(VIA_ERROR_TYPE, VIA_ERROR_TIMEOUT); |
| 8077 | break; |
| 8078 | case HTTP_STATUS_NOT_FOUND: |
| 8079 | SET_VIA_STRING(VIA_ERROR_TYPE, VIA_ERROR_SERVER); |
| 8080 | break; |
| 8081 | case HTTP_STATUS_FORBIDDEN: |
nothing calls this directly
no test coverage detected