bool f_dangling_server_proxy_new_request(const String& host) { if (host.empty()) { raise_warning("proxy new request needs host name"); return false; } Transport *transport = g_context->getTransport(); if (transport == NULL) { return false; } if (!transport->getHeader(DANGLING_HEADER).empty()) { // if we are processing a dangling server request, do not do it again return false; } std::string url = std::string("http://") + host.data() + ":" + boost::lexical_cast<std::string>(RuntimeOption::ServerPort) + transport->getServerObject(); int code = 0; std::string error; StringBuffer response; HeaderMap headers; headers[DANGLING_HEADER].push_back("1"); if (!HttpProtocol::ProxyRequest(transport, false, url, code, error, response, &headers)) { return false; } transport->setResponse(code, "dangling_server_proxy_new_request"); echo(response.detach()); return true; }
bool f_dangling_server_proxy_old_request() { static bool s_detected_dangling_server = true; if (!s_detected_dangling_server || SatelliteServerInfo::DanglingServerPort == 0) { return false; } Transport *transport = g_context->getTransport(); if (transport == NULL) { return false; } if (!transport->getHeader(DANGLING_HEADER).empty()) { // if we are processing a dangling server request, do not do it again return false; } std::string url = "http://localhost:" + boost::lexical_cast<std::string>(SatelliteServerInfo::DanglingServerPort) + transport->getServerObject(); int code = 0; std::string error; StringBuffer response; HeaderMap headers; headers[DANGLING_HEADER].push_back("1"); if (!HttpProtocol::ProxyRequest(transport, false, url, code, error, response, &headers)) { s_detected_dangling_server = false; return false; } transport->setResponse(code, "dangling_server_proxy_old_request"); echo(response.detach()); return true; }
Variant f_http_response_code(int response_code /* = 0 */) { Transport *transport = g_context->getTransport(); if (!transport) { raise_warning("Unable to access response code, no transport"); return false; } int old_code = transport->getResponseCode(); if (response_code) { transport->setResponse(response_code, "explicit_header_response_code"); } if (old_code) { return old_code; } return response_code ? true : false; }
Variant HHVM_FUNCTION(http_response_code, int response_code /* = 0 */) { Transport *transport = g_context->getTransport(); if (transport) { *s_response_code = transport->getResponseCode(); if (response_code) { transport->setResponse(response_code); } } int old_code = *s_response_code; if (response_code) { *s_response_code = response_code; } if (old_code) { return old_code; } return response_code ? true : false; }
void HHVM_FUNCTION(header, const String& str, bool replace /* = true */, int http_response_code /* = 0 */) { if (HHVM_FN(headers_sent)()) { raise_warning("Cannot modify header information - headers already sent"); } String header = HHVM_FN(rtrim)(str); // new line safety check // NOTE: PHP actually allows "\n " and "\n\t" to fall through. Is that bad // for security? if (header.find('\n') >= 0 || header.find('\r') >= 0) { raise_warning("Header may not contain more than a single header, " "new line detected"); return; } Transport *transport = g_context->getTransport(); if (transport && header.size()) { const char *header_line = header.data(); // handle single line of status code if ((header.size() >= 5 && strncasecmp(header_line, "HTTP/", 5) == 0) || (header.size() >= 7 && strncasecmp(header_line, "Status:", 7) == 0)) { int code = 200; const char *reason = nullptr; for (const char *ptr = header_line + 5; *ptr; ptr++) { if (*ptr == ' ' && *(ptr + 1) != ' ') { code = atoi(ptr + 1); for (ptr++; *ptr; ptr++) { if (*ptr == ' ' && *(ptr + 1) != ' ') { reason = ptr + 1; break; } } break; } } if (code) { transport->setResponse(code, reason); } return; } const char *colon_offset = strchr(header_line, ':'); String newHeader; if (colon_offset) { if (!strncasecmp(header_line, "Content-Type", colon_offset - header_line)) { const char *ptr = colon_offset+1, *mimetype = NULL; while (*ptr == ' ') ptr++; mimetype = ptr; if (strncmp(mimetype, "text/", 5) == 0 && strstr(mimetype, "charset=") == NULL) { newHeader = header + ";charset=utf-8"; } } } if (replace) { transport->replaceHeader(newHeader.empty() ? header : newHeader); } else { transport->addHeader(newHeader.empty() ? header : newHeader); } if (http_response_code) { transport->setResponse(http_response_code); } } }