Beispiel #1
0
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;
}
Beispiel #2
0
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);
        }
    }
}