<commit_before>/*
  +----------------------------------------------------------------------+
  | linger_framework                                                     |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2016 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | <EMAIL> so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: liubang <<EMAIL>>                               |
  +----------------------------------------------------------------------+
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_linger_framework.h"
#include "linger_response.h"
#include "php_output.h"
#include "SAPI.h"

#include "zend_smart_str.h"
#include "ext/json/php_json.h"

zend_class_entry *response_ce;

ZEND_BEGIN_ARG_INFO_EX(linger_framework_response_void_arginfo, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(linger_framework_response_header_arginfo, 0, 0, 2)
ZEND_ARG_INFO(0, key)
ZEND_ARG_INFO(0, val)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(linger_framework_response_status_arginfo, 0, 0, 0)
ZEND_ARG_INFO(0, status)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(linger_framework_response_body_arginfo, 0, 0, 0)
ZEND_ARG_INFO(0, body)
ZEND_END_ARG_INFO()

zval *linger_response_instance(zval *this)
{
    zval *instance = zend_read_static_property(response_ce, ZEND_STRL(RESPONSE_PROPERTIES_INSTANCE), 1);

    if (instance && IS_OBJECT == Z_TYPE_P(instance) &&
            instanceof_function(Z_OBJCE_P(instance), response_ce)) {
        return instance;
    }

    if (Z_ISUNDEF_P(this)) {
        object_init_ex(this, response_ce);
    }

    zval headers = {{0}};
    array_init(&headers);
    zend_update_property(response_ce, this, ZEND_STRL(RESPONSE_PROPERTIES_HEADER), &headers);
    zval_ptr_dtor(&headers);

    zval status = {{0}};
    ZVAL_LONG(&status, 200);
    zend_update_property(response_ce, this, ZEND_STRL(RESPONSE_PROPERTIES_STATUS), &status);
    zval_ptr_dtor(&status);

    zval body = {{0}};
    ZVAL_STRING(&body, "");
    zend_update_property(response_ce, this, ZEND_STRL(RESPONSE_PROPERTIES_BODY), &body);
    zval_ptr_dtor(&body);

    zend_update_static_property(response_ce, ZEND_STRL(RESPONSE_PROPERTIES_INSTANCE), this);

    return this;
}

void linger_response_send(zval *this)
{
    zval *headers = zend_read_property(response_ce, this, ZEND_STRL(RESPONSE_PROPERTIES_HEADER), 1, NULL);
    zval *body = zend_read_property(response_ce, this, ZEND_STRL(RESPONSE_PROPERTIES_BODY), 1, NULL);
    zval *status = zend_read_property(response_ce, this, ZEND_STRL(RESPONSE_PROPERTIES_STATUS), 1, NULL);

    SG(sapi_headers).http_response_code = (int)Z_LVAL_P(status);

    if (!SG(headers_sent)) {
        zval *header = NULL;
        zend_string *key = NULL;
        ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(headers), key, header) {
            char *line;
            int len = spprintf(&line, 0, "%s:%s", ZSTR_VAL(key), Z_STRVAL_P(header));
            sapi_header_line ctr = {
                .line = line,
                .line_len = (uint32_t)len,
            };
            sapi_header_op(SAPI_HEADER_REPLACE, &ctr);
            linger_efree(line);
        }
        ZEND_HASH_FOREACH_END();
    }

    PHPWRITE(Z_STRVAL_P(body), Z_STRLEN_P(body));
}

static int check_response_status(int status)
{
    return (status == 100 || status == 101 || status == 200 || status == 201
            || status == 202 || status == 203 || status == 204 || status == 205
            || status == 206 || status == 300 || status == 301 || status == 302
            || status == 303 || status == 304 || status == 305 || status == 400
            || status == 401 || status == 402 || status == 403 || status == 404<commit_msg>Call fastcgi_finish_request after request finished<commit_after>/*
  +----------------------------------------------------------------------+
  | linger_framework                                                     |
  +----------------------------------------------------------------------+
  | Copyright (c) 1997-2016 The PHP Group                                |
  +----------------------------------------------------------------------+
  | This source file is subject to version 3.01 of the PHP license,      |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.php.net/license/3_01.txt                                  |
  | If you did not receive a copy of the PHP license and are unable to   |
  | obtain it through the world-wide-web, please send a note to          |
  | <EMAIL> so we can mail you a copy immediately.               |
  +----------------------------------------------------------------------+
  | Author: liubang <<EMAIL>>                               |
  +----------------------------------------------------------------------+
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "php.h"
#include "php_linger_framework.h"
#include "linger_response.h"
#include "php_output.h"
#include "SAPI.h"

#include "Zend/zend_interfaces.h"
#include "zend_smart_str.h"
#include "ext/json/php_json.h"

zend_class_entry *response_ce;

ZEND_BEGIN_ARG_INFO_EX(linger_framework_response_void_arginfo, 0, 0, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(linger_framework_response_header_arginfo, 0, 0, 2)
ZEND_ARG_INFO(0, key)
ZEND_ARG_INFO(0, val)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(linger_framework_response_status_arginfo, 0, 0, 0)
ZEND_ARG_INFO(0, status)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(linger_framework_response_body_arginfo, 0, 0, 0)
ZEND_ARG_INFO(0, body)
ZEND_END_ARG_INFO()

zval *linger_response_instance(zval *this)
{
    zval *instance = zend_read_static_property(response_ce, ZEND_STRL(RESPONSE_PROPERTIES_INSTANCE), 1);

    if (instance && IS_OBJECT == Z_TYPE_P(instance) &&
            instanceof_function(Z_OBJCE_P(instance), response_ce)) {
        return instance;
    }

    if (Z_ISUNDEF_P(this)) {
        object_init_ex(this, response_ce);
    }

    zval headers = {{0}};
    array_init(&headers);
    zend_update_property(response_ce, this, ZEND_STRL(RESPONSE_PROPERTIES_HEADER), &headers);
    zval_ptr_dtor(&headers);

    zval status = {{0}};
    ZVAL_LONG(&status, 200);
    zend_update_property(response_ce, this, ZEND_STRL(RESPONSE_PROPERTIES_STATUS), &status);
    zval_ptr_dtor(&status);

    zval body = {{0}};
    ZVAL_STRING(&body, "");
    zend_update_property(response_ce, this, ZEND_STRL(RESPONSE_PROPERTIES_BODY), &body);
    zval_ptr_dtor(&body);

    zend_update_static_property(response_ce, ZEND_STRL(RESPONSE_PROPERTIES_INSTANCE), this);

    return this;
}

void linger_response_send(zval *this)
{
    zval *headers = zend_read_property(response_ce, this, ZEND_STRL(RESPONSE_PROPERTIES_HEADER), 1, NULL);
    zval *body = zend_read_property(response_ce, this, ZEND_STRL(RESPONSE_PROPERTIES_BODY), 1, NULL);
    zval *status = zend_read_property(response_ce, this, ZEND_STRL(RESPONSE_PROPERTIES_STATUS), 1, NULL);

    SG(sapi_headers).http_response_code = (int)Z_LVAL_P(status);

    if (!SG(headers_sent)) {
        zval *header = NULL;
        zend_string *key = NULL;
        ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(headers), key, header) {
            char *line;
            int len = spprintf(&line, 0, "%s:%s", ZSTR_VAL(key), Z_STRVAL_P(header));
            sapi_header_line ctr = {
                .line = line,
                .line_len = (uint32_t)len,
            };
            sapi_header_op(SAPI_HEADER_REPLACE, &ctr);
            linger_efree(line);
        }
        ZEND_HASH_FOREACH_END();
    }

    PHPWRITE(Z_STRVAL_P(body), Z_STRLEN_P(body));

    if (strcmp(sapi_module.name, "fpm-fcgi") == 0) {
        zend_call_method_with_0_params(NULL, NULL, NULL, "fastcgi_finish_request", NULL);
    }
}

static int check_response_status(int status)
{
    return (status == 100 || status == 101 || status == 200 || status == 201
            || status == 202 || status == 203 || status == 204 || status == 205
            || status == 206 || status == 300 || status == 301 || status == 302
            || status == 303 || status == 304 || status == 305 || status == 400
            || status == 401 || status == 402 || status == 403 || status == 404
{'fraction_non_alphanumeric': 0.18666517005275565, 'fraction_numerical': 0.023347177012010327, 'mean_word_length': 2.2975573649148777, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2923969', 'n_tokens_mistral': 3125, 'n_tokens_neox': 2869, 'n_words': 580}