| /** @file | |
| Licensed to the Apache Software Foundation (ASF) under one | |
| or more contributor license agreements. See the NOTICE file | |
| distributed with this work for additional information | |
| regarding copyright ownership. The ASF licenses this file | |
| to you under the Apache License, Version 2.0 (the | |
| "License"); you may not use this file except in compliance | |
| with the License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| */ | |
| #include "response.h" | |
| #include <cinttypes> | |
| #include <cstring> | |
| #include <mutex> | |
| #include "ts/ts.h" | |
| // canned body string for a 416, stolen from nginx | |
| std::string const & | |
| bodyString416() | |
| { | |
| static std::string bodystr; | |
| static std::mutex mutex; | |
| std::lock_guard<std::mutex> const guard(mutex); | |
| if (bodystr.empty()) { | |
| bodystr.append("<html>\n"); | |
| bodystr.append("<head><title>416 Requested Range Not Satisfiable</title></head>\n"); | |
| bodystr.append("<body bgcolor=\"white\">\n"); | |
| bodystr.append("<center><h1>416 Requested Range Not Satisfiable</h1></center>"); | |
| bodystr.append("<hr><center>ATS/"); | |
| bodystr.append(TS_VERSION_STRING); | |
| bodystr.append("</center>\n"); | |
| bodystr.append("</body>\n"); | |
| bodystr.append("</html>\n"); | |
| } | |
| return bodystr; | |
| } | |
| // Form a 502 response, preliminary | |
| std::string | |
| string502(int const httpver) | |
| { | |
| static std::string msg; | |
| static std::mutex mutex; | |
| std::lock_guard<std::mutex> const guard(mutex); | |
| if (msg.empty()) { | |
| std::string bodystr; | |
| bodystr.append("<html>\n"); | |
| bodystr.append("<head><title>502 Bad Gateway</title></head>\n"); | |
| bodystr.append("<body bgcolor=\"white\">\n"); | |
| bodystr.append("<center><h1>502 Bad Gateway: Missing/Malformed " | |
| "Content-Range</h1></center>"); | |
| bodystr.append("<hr><center>ATS/"); | |
| bodystr.append(TS_VERSION_STRING); | |
| bodystr.append("</center>\n"); | |
| bodystr.append("</body>\n"); | |
| bodystr.append("</html>\n"); | |
| char hverstr[64]; | |
| int const hlen = | |
| snprintf(hverstr, sizeof(hverstr), "HTTP/%d.%d 502 Bad Gateway\r\n", TS_HTTP_MAJOR(httpver), TS_HTTP_MINOR(httpver)); | |
| msg.append(hverstr, hlen); | |
| char clenstr[1024]; | |
| int const clen = snprintf(clenstr, sizeof(clenstr), "%lu", bodystr.size()); | |
| msg.append("Content-Length: "); | |
| msg.append(clenstr, clen); | |
| msg.append("\r\n"); | |
| msg.append("\r\n"); | |
| msg.append(bodystr); | |
| } | |
| return msg; | |
| } | |
| // Form the response to a sliced PURGE, once every block has been walked | |
| bool | |
| form_purge_response(HdrMgr &hdrmgr, TSHttpStatus const status) | |
| { | |
| if (!hdrmgr.create_response(status)) { | |
| return false; | |
| } | |
| // The core adds Date, Age, Server and Connection to an intercept's response | |
| HttpHeader header(hdrmgr.m_buffer, hdrmgr.m_lochdr); | |
| header.setKeyVal(TS_MIME_FIELD_CONTENT_LENGTH, TS_MIME_LEN_CONTENT_LENGTH, "0", 1); | |
| return true; | |
| } | |
| void | |
| form416HeaderAndBody(HttpHeader &header, int64_t const contentlen, std::string const &bodystr) | |
| { | |
| header.removeKey(TS_MIME_FIELD_LAST_MODIFIED, TS_MIME_LEN_LAST_MODIFIED); | |
| header.removeKey(TS_MIME_FIELD_EXPIRES, TS_MIME_LEN_EXPIRES); | |
| header.removeKey(TS_MIME_FIELD_ETAG, TS_MIME_LEN_ETAG); | |
| header.removeKey(TS_MIME_FIELD_ACCEPT_RANGES, TS_MIME_LEN_ACCEPT_RANGES); | |
| header.setStatus(TS_HTTP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE); | |
| char const *const reason = TSHttpHdrReasonLookup(TS_HTTP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE); | |
| header.setReason(reason, strlen(reason)); | |
| char bufstr[256]; | |
| int buflen = snprintf(bufstr, sizeof(bufstr), "%lu", bodystr.size()); | |
| header.setKeyVal(TS_MIME_FIELD_CONTENT_LENGTH, TS_MIME_LEN_CONTENT_LENGTH, bufstr, buflen); | |
| static char const *const ctypestr = "text/html"; | |
| static int const ctypelen = strlen(ctypestr); | |
| header.setKeyVal(TS_MIME_FIELD_CONTENT_TYPE, TS_MIME_LEN_CONTENT_TYPE, ctypestr, ctypelen); | |
| buflen = snprintf(bufstr, 255, "*/%" PRId64, contentlen); | |
| header.setKeyVal(TS_MIME_FIELD_CONTENT_RANGE, TS_MIME_LEN_CONTENT_RANGE, bufstr, buflen); | |
| } |