-
- return SUCCESS;
-}
-/* }}} */
-
-/* {{{ int http_modified_match(char *, time_t) */
-PHP_HTTP_API int _http_modified_match_ex(const char *entry, const time_t t,
- const int enforce_presence TSRMLS_DC)
-{
- int retval;
- zval *zmodified;
- char *modified, *chr_ptr;
-
- HTTP_GSC(zmodified, entry, !enforce_presence);
-
- modified = estrndup(Z_STRVAL_P(zmodified), Z_STRLEN_P(zmodified));
- if (chr_ptr = strrchr(modified, ';')) {
- chr_ptr = 0;
- }
- retval = (t <= http_parse_date(modified));
- efree(modified);
- return retval;
-}
-/* }}} */
-
-/* {{{ int http_etag_match(char *, char *) */
-PHP_HTTP_API int _http_etag_match_ex(const char *entry, const char *etag,
- const int enforce_presence TSRMLS_DC)
-{
- zval *zetag;
- char *quoted_etag;
- STATUS result;
-
- HTTP_GSC(zetag, entry, !enforce_presence);
-
- if (NULL != strchr(Z_STRVAL_P(zetag), '*')) {
- return 1;
- }
-
- quoted_etag = (char *) emalloc(strlen(etag) + 3);
- sprintf(quoted_etag, "\"%s\"", etag);
-
- if (!strchr(Z_STRVAL_P(zetag), ',')) {
- result = !strcmp(Z_STRVAL_P(zetag), quoted_etag);
- } else {
- result = (NULL != strstr(Z_STRVAL_P(zetag), quoted_etag));
- }
- efree(quoted_etag);
- return result;
-}
-/* }}} */
-
-/* {{{ STATUS http_send_last_modified(int) */
-PHP_HTTP_API STATUS _http_send_last_modified(const time_t t TSRMLS_DC)
-{
- char *date = NULL;
- if (date = http_date(t)) {
- char modified[96] = "Last-Modified: ";
- strcat(modified, date);
- efree(date);
-
- /* remember */
- HTTP_G(lmod) = t;
-
- return http_send_header(modified);
- }
- return FAILURE;
-}
-/* }}} */
-
-/* {{{ static STATUS http_send_etag(char *, int) */
-PHP_HTTP_API STATUS _http_send_etag(const char *etag,
- const int etag_len TSRMLS_DC)
-{
- STATUS status;
- char *etag_header;
-
- if (!etag_len){
- php_error_docref(NULL TSRMLS_CC,E_ERROR,
- "Attempt to send empty ETag (previous: %s)\n", HTTP_G(etag));
- return FAILURE;
- }
-
- /* remember */
- if (HTTP_G(etag)) {
- efree(HTTP_G(etag));
- }
- HTTP_G(etag) = estrdup(etag);
-
- etag_header = ecalloc(1, sizeof("ETag: \"\"") + etag_len);
- sprintf(etag_header, "ETag: \"%s\"", etag);
- if (SUCCESS != (status = http_send_header(etag_header))) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't send '%s' header", etag_header);
- }
- efree(etag_header);
- return status;
-}
-/* }}} */
-
-/* {{{ STATUS http_send_cache_control(char *, size_t) */
-PHP_HTTP_API STATUS _http_send_cache_control(const char *cache_control,
- const size_t cc_len TSRMLS_DC)
-{
- STATUS status;
- char *cc_header = ecalloc(1, sizeof("Cache-Control: ") + cc_len);
-
- sprintf(cc_header, "Cache-Control: %s", cache_control);
- if (SUCCESS != (status = http_send_header(cc_header))) {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE,
- "Could not send '%s' header", cc_header);
- }
- efree(cc_header);
- return status;
-}
-/* }}} */
-
-/* {{{ STATUS http_send_content_type(char *, size_t) */
-PHP_HTTP_API STATUS _http_send_content_type(const char *content_type,
- const size_t ct_len TSRMLS_DC)
-{
- STATUS status;
- char *ct_header;
-
- if (!strchr(content_type, '/')) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "Content-Type '%s' doesn't seem to consist of a primary and a secondary part",
- content_type);
- return FAILURE;
- }
-
- /* remember for multiple ranges */
- if (HTTP_G(ctype)) {
- efree(HTTP_G(ctype));
- }
- HTTP_G(ctype) = estrndup(content_type, ct_len);
-
- ct_header = ecalloc(1, sizeof("Content-Type: ") + ct_len);
- sprintf(ct_header, "Content-Type: %s", content_type);
-
- if (SUCCESS != (status = http_send_header(ct_header))) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "Couldn't send '%s' header", ct_header);
- }
- efree(ct_header);
- return status;
-}
-/* }}} */
-
-/* {{{ STATUS http_send_content_disposition(char *, size_t, zend_bool) */
-PHP_HTTP_API STATUS _http_send_content_disposition(const char *filename,
- const size_t f_len, const int send_inline TSRMLS_DC)
-{
- STATUS status;
- char *cd_header;
-
- if (send_inline) {
- cd_header = ecalloc(1, sizeof("Content-Disposition: inline; filename=\"\"") + f_len);
- sprintf(cd_header, "Content-Disposition: inline; filename=\"%s\"", filename);
- } else {
- cd_header = ecalloc(1, sizeof("Content-Disposition: attachment; filename=\"\"") + f_len);
- sprintf(cd_header, "Content-Disposition: attachment; filename=\"%s\"", filename);
- }
-
- if (SUCCESS != (status = http_send_header(cd_header))) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't send '%s' header", cd_header);
- }
- efree(cd_header);
- return status;
-}
-/* }}} */
-
-/* {{{ STATUS http_cache_last_modified(time_t, time_t, char *, size_t) */
-PHP_HTTP_API STATUS _http_cache_last_modified(const time_t last_modified,
- const time_t send_modified, const char *cache_control, const size_t cc_len TSRMLS_DC)
-{
- if (cc_len) {
- http_send_cache_control(cache_control, cc_len);
- }
-
- if (http_modified_match("HTTP_IF_MODIFIED_SINCE", last_modified)) {
- if (SUCCESS == http_send_status(304)) {
- zend_bailout();
- } else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not send 304 Not Modified");
- return FAILURE;
- }
- }
- return http_send_last_modified(send_modified);
-}
-/* }}} */
-
-/* {{{ STATUS http_cache_etag(char *, size_t, char *, size_t) */
-PHP_HTTP_API STATUS _http_cache_etag(const char *etag, const size_t etag_len,
- const char *cache_control, const size_t cc_len TSRMLS_DC)
-{
- if (cc_len) {
- http_send_cache_control(cache_control, cc_len);
- }
-
- if (etag_len) {
- http_send_etag(etag, etag_len);
- if (http_etag_match("HTTP_IF_NONE_MATCH", etag)) {
- if (SUCCESS == http_send_status(304)) {
- zend_bailout();
- } else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not send 304 Not Modified");
- return FAILURE;
- }
- }
- }
-
- /* if no etag is given and we didn't already start ob_etaghandler -- start it */
- if (!HTTP_G(etag_started)) {
- if (SUCCESS == http_start_ob_handler(_http_ob_etaghandler, "ob_etaghandler", 4096, 1)) {
- HTTP_G(etag_started) = 1;
- return SUCCESS;
- } else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not start ob_etaghandler");
- return FAILURE;
- }
- }
- return SUCCESS;
-}
-/* }}} */
-
-/* {{{ char *http_absolute_uri(char *) */
-PHP_HTTP_API char *_http_absolute_uri_ex(
- const char *url, size_t url_len,
- const char *proto, size_t proto_len,
- const char *host, size_t host_len,
- unsigned port TSRMLS_DC)
-{
-#if defined(PHP_WIN32) || defined(HAVE_NETDB_H)
- struct servent *se;
-#endif
- php_url *purl, furl = {NULL};
- size_t full_len = 0;
- zval *zhost = NULL;
- char *scheme = NULL, *URL = ecalloc(1, HTTP_URI_MAXLEN + 1);
-
- if ((!url || !url_len) && (
- (!(url = SG(request_info).request_uri)) ||
- (!(url_len = strlen(SG(request_info).request_uri))))) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "Cannot build an absolute URI if supplied URL and REQUEST_URI is empty");
- return NULL;
- }
-
- if (!(purl = php_url_parse((char *) url))) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not parse supplied URL");
- return NULL;
- }
-
- furl.user = purl->user;
- furl.pass = purl->pass;
- furl.path = purl->path;
- furl.query = purl->query;
- furl.fragment = purl->fragment;
-
- if (proto && proto_len) {
- furl.scheme = scheme = estrdup(proto);
- } else if (purl->scheme) {
- furl.scheme = purl->scheme;
-#if defined(PHP_WIN32) || defined(HAVE_NETDB_H)
- } else if (port && (se = getservbyport(port, "tcp"))) {
- furl.scheme = (scheme = estrdup(se->s_name));
-#endif
- } else {
- furl.scheme = "http";
- }
-
- if (port) {
- furl.port = port;
- } else if (purl->port) {
- furl.port = purl->port;
- } else if (strncmp(furl.scheme, "http", 4)) {
-#if defined(PHP_WIN32) || defined(HAVE_NETDB_H)
- if (se = getservbyname(furl.scheme, "tcp")) {
- furl.port = se->s_port;
- }