国产+高潮+在线,国产 av 仑乱内谢,www国产亚洲精品久久,51国产偷自视频区视频,成人午夜精品网站在线观看

workman沒有正確設(shè)置sapi_globals_struct的request_info

venchi

問題描述

使用workman框架,寫一個簡單的soap服務(wù),訪問wsdl無法正常獲取服務(wù)定義的xml內(nèi)容。經(jīng)調(diào)試后發(fā)現(xiàn)workman收到請求后沒有正確設(shè)置 sapi_globals_struct.request_info

程序代碼或配置

workman代碼

<?php
use Workerman\Worker;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

// 創(chuàng)建一個Worker監(jiān)聽2345端口,使用http協(xié)議通訊
$http_worker = new Worker("http://0.0.0.0:2345");

// 設(shè)置進(jìn)程名稱
$http_worker->name = 'SoapServerWorker';

// 啟動4個進(jìn)程對外提供服務(wù)
$http_worker->count = 1;

class SoapServ {
    public function sayHello($name) {
        return "Hello, " . $name;
    }
}

// 當(dāng)有客戶端連接時
$http_worker->onConnect = function ($connection) {
    echo "新連接:{$connection->id}\n";
};

// 接收到瀏覽器發(fā)送的數(shù)據(jù)時回復(fù)hello world給瀏覽器
$http_worker->onMessage = function(TcpConnection $connection, Request $request)
{
    if ($request->path() == '/serv') {
        try {

            ini_set('display_errors', 'On');
            ini_set('soap.wsdl_cache_enabled', "0"); //關(guān)閉wsdl緩存
            ob_start();
            $server = new SoapServer('/var/www/interfacems/workman/webman.wsdl', array('soap_version' => SOAP_1_2));
            $server->setClass('SoapServ');
            $server->handle();
            // readfile('webman.wsdl');
            $ret = ob_get_clean();
            $response = new Response(200, [
                'Content-Type' => 'text/xml; charset=utf-8',
            ], $ret);

            $connection->send($response);
            return;
        } catch (Exception $e) {
            // 錯誤處理邏輯
            $connection->send("Error: " . $e->getMessage());
        }
    } elseif ($request->path() == '/client') {
        try {
            $client = new SoapClient("http://localhost:8080/serv?wsdl");
            $fs = $client->__getFunctions();
            // 向?yàn)g覽器發(fā)送hello world
            $response = new Response(200, [
                'Content-Type' => 'text/json; charset=utf-8',
            ], json_encode($fs, JSON_UNESCAPED_UNICODE));
            $connection->send($response);
        } catch (Exception $e) {
            // 錯誤處理邏輯
            $connection->send("Error: " . $e->getMessage());
        }
    } else {
        // 如果不是預(yù)期的路徑,可以發(fā)送404響應(yīng)或其他邏輯
        $connection->send("Not Found");
    }
};

// 運(yùn)行worker
Worker::runAll();

調(diào)試soap代碼 soap.c:1158


    printf("request_method = %s query_string=%s \n", SG(request_info).request_method, SG(request_info).query_string); 
    // 這里修改了源碼,打印了request_info屬性值,輸出為null

    if (SG(request_info).request_method &&
        strcmp(SG(request_info).request_method, "GET") == 0 &&
        SG(request_info).query_string &&
        stricmp(SG(request_info).query_string, "wsdl") == 0) {

        if (service->sdl) {
/*
            char *hdr = emalloc(sizeof("Location: ")+strlen(service->sdl->source));
            strcpy(hdr,"Location: ");
            strcat(hdr,service->sdl->source);
            sapi_add_header(hdr, sizeof("Location: ")+strlen(service->sdl->source)-1, 1);
            efree(hdr);
*/
            zval readfile, readfile_ret, param;

            sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1);
            ZVAL_STRING(&param, service->sdl->source);
            ZVAL_STRING(&readfile, "readfile");
            if (call_user_function(EG(function_table), NULL, &readfile, &readfile_ret, 1, &param ) == FAILURE) {
                soap_server_fault("Server", "Couldn't find WSDL", NULL, NULL, NULL);
            }

            zval_ptr_dtor(&param);
            zval_ptr_dtor_str(&readfile);
            zval_ptr_dtor(&readfile_ret);

            SOAP_SERVER_END_CODE();
            return;
        } else {
            soap_server_fault("Server", "WSDL generation is not supported yet", NULL, NULL, NULL);
/*
            sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8"), 1);
            PUTS("<?xml version=\"1.0\" ?>\n<definitions\n");
            PUTS("    xmlns=\"http://schemas.xmlsoap.org/wsdl/\"\n");
            PUTS("    targetNamespace=\"");
            PUTS(service->uri);
            PUTS("\">\n");
            PUTS("</definitions>");
*/
            SOAP_SERVER_END_CODE();
            return;
        }

輸出:

[root@localhost workman]# php test.php start
Workerman[test.php] start in DEBUG mode
------------------------------------------- WORKERMAN --------------------------------------------
Workerman version:4.1.15          PHP version:8.3.6           Event-Loop:\Workerman\Events\Select
-------------------------------------------- WORKERS ---------------------------------------------
proto   user            worker              listen                 processes    status           
tcp     root            SoapServerWorker    http://0.0.0.0:2345    1             [OK]            
--------------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.

request_method = (null) query_string=(null)

操作系統(tǒng)環(huán)境及workerman/webman等具體版本

workman版本信息: "workerman/workerman": "^4.1"

操作系統(tǒng)環(huán)境信息:

[root@localhost php-8.3.6]# cat /etc/os-release 
NAME="openEuler"
VERSION="22.03 (LTS-SP3)"
ID="openEuler"
VERSION_ID="22.03"
PRETTY_NAME="openEuler 22.03 (LTS-SP3)"
ANSI_COLOR="0;31"

[root@localhost php-8.3.6]# php -v
PHP 8.3.6 (cli) (built: Jul  4 2024 11:02:42) (ZTS DEBUG)
Copyright (c) The PHP Group
Zend Engine v4.3.6, Copyright (c) Zend Technologies
[root@localhost php-8.3.6]# php --ri soap

soap

Soap Client => enabled
Soap Server => enabled

Directive => Local Value => Master Value
soap.wsdl_cache_enabled => On => On
soap.wsdl_cache_dir => /tmp => /tmp
soap.wsdl_cache_ttl => 86400 => 86400
soap.wsdl_cache => 1 => 1
soap.wsdl_cache_limit => 5 => 5
705 2 0
2個回答

walkor 打賞

webman是一個php cli的框架,不是c擴(kuò)展,沒有辦法直接操作更改內(nèi)核結(jié)構(gòu)體,除非php提供了接口。

  • venchi 2024-07-04

    使用php cli啟動服務(wù)是會正常賦值的。
    啟動服務(wù):

    [root@localhost interfacems]# php -S 0.0.0.0:2345
    [Thu Jul  4 16:55:03 2024] PHP 8.3.6 Development Server (http://0.0.0.0:2345) started
    [Thu Jul  4 16:55:21 2024] 127.0.0.1:38046 Accepted
    request_method = GET query_string=wsdl 
    [Thu Jul  4 16:55:21 2024] 127.0.0.1:38046 [200]: GET /soap.php?wsdl
    [Thu Jul  4 16:55:21 2024] 127.0.0.1:38046 Closing
    [Thu Jul  4 16:56:40 2024] 127.0.0.1:36138 Accepted
    request_method = GET query_string=wsdl 

    測試代碼:

    <?php
    class SoapServ {
        public function sayHello($name) {
            return "Hello, " . $name;
        }
    }
    
    $server = new SoapServer('/var/www/interfacems/workman/webman.wsdl', array('soap_version' => SOAP_1_2));
    $server->setClass('SoapServ');
    $server->handle();

    測試命令:curl http://localhost:2345/soap.php?wsdl

  • walkor 2024-07-04

    php -S 是啟動php內(nèi)置的server,和php cli不是一回事

  • venchi 2024-07-05

    調(diào)試php -S 也是第一步進(jìn)入的是sapi/cli下面的cli_server
    php -S棧信息如下:

    (gdb) bt
    #0  0x00007f9e76627289 in select () from /usr/lib64/libc.so.6
    #1  0x0000000000d2b154 in php_cli_server_poller_poll (poller=0x1c23bc8 <server+8>, tv=0x7ffe9a7a5c20)
        at /root/php/php-8.3.6/sapi/cli/php_cli_server.c:880
    #2  0x0000000000d2f71c in php_cli_server_do_event_loop (server=0x1c23bc0 <server>) at /root/php/php-8.3.6/sapi/cli/php_cli_server.c:2756
    #3  0x0000000000d2fabd in do_cli_server (argc=3, argv=0x2f7fa60) at /root/php/php-8.3.6/sapi/cli/php_cli_server.c:2890
    #4  0x0000000000d25ca9 in main (argc=3, argv=0x2f7fa60) at /root/php/php-8.3.6/sapi/cli/php_cli.c:1343

    workman調(diào)用棧如下:

    (gdb) zbacktrace 
    [0x7f87e6c17820] pcntl_wait(reference, 2) [internal function]
    [0x7f87e6c172f0] Workerman\Worker->monitorWorkersForLinux() /var/www/interfacems/workman/vendor/workerman/workerman/Worker.php:1743 
    [0x7f87e6c17250] Workerman\Worker->monitorWorkers() /var/www/interfacems/workman/vendor/workerman/workerman/Worker.php:1724 
    [0x7f87e6c17130] Workerman\Worker->runAll() /var/www/interfacems/workman/vendor/workerman/workerman/Worker.php:562 
    [0x7f87e6c17020] (main) /var/www/interfacems/workman/test.php:72 
    (gdb) bt
    #0  0x00007f87e6fe016a in wait4 () from /usr/lib64/libc.so.6
    #1  0x000000000087f51b in zif_pcntl_wait (execute_data=0x7f87e6c17820, return_value=0x7f87e6c173f0) at /root/php/php-8.3.6/ext/pcntl/pcntl.c:325
    #2  0x0000000000be891d in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER () at /root/php/php-8.3.6/Zend/zend_vm_execute.h:1337
    #3  0x0000000000c667ca in execute_ex (ex=0x7f87e6c17020) at /root/php/php-8.3.6/Zend/zend_vm_execute.h:57216
    #4  0x0000000000c6b085 in zend_execute (op_array=0x7f87e6c7d140, return_value=0x0) at /root/php/php-8.3.6/Zend/zend_vm_execute.h:61604
    #5  0x0000000000ba72b4 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /root/php/php-8.3.6/Zend/zend.c:1891
    #6  0x0000000000aec860 in php_execute_script (primary_file=0x7ffd8516b780) at /root/php/php-8.3.6/main/main.c:2507
    #7  0x0000000000d24f57 in do_cli (argc=3, argv=0x376df50) at /root/php/php-8.3.6/sapi/cli/php_cli.c:966
    #8  0x0000000000d25c8d in main (argc=3, argv=0x376df50) at /root/php/php-8.3.6/sapi/cli/php_cli.c:1340

    看了源碼是一個是 do_cli 一個是do_cli_server,難道是php cli就沒有設(shè)置request_info?

venchi

已經(jīng)通過改寫實(shí)現(xiàn)soapserver的功能,手動判斷是否有wsdl的請求,如有則返回wsdl文件內(nèi)容。
代碼如下:

<?php
use Workerman\Worker;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

// 創(chuàng)建一個Worker監(jiān)聽2345端口,使用http協(xié)議通訊
$http_worker = new Worker("http://0.0.0.0:2345");

// 將屏幕打印輸出到Worker::$stdoutFile指定的文件中
Worker::$stdoutFile = 'stdout.log';

// 設(shè)置進(jìn)程名稱
$http_worker->name = 'SoapServerWorker';

// 啟動4個進(jìn)程對外提供服務(wù)
$http_worker->count = 1;

class SoapServ {
    public function sayHello($name) {
        return "Hello, " . $name;
    }
}

// 當(dāng)有客戶端連接時
$http_worker->onConnect = function ($connection) {
    echo "新連接:{$connection->id}\n";
};

// 接收到瀏覽器發(fā)送的數(shù)據(jù)時回復(fù)hello world給瀏覽器
$http_worker->onMessage = function(TcpConnection $connection, Request $request)
{
    if ($request->path() == '/serv') {
        try {

            // ini_set('display_errors', 'On');
            // ini_set('soap.wsdl_cache_enabled', "0"); //關(guān)閉wsdl緩存

            $wsdl = file_get_contents('/var/www/interfacems/workman/webman.wsdl');
            if ($request->method() == 'GET' && $request->get('wsdl') !== null) {
                $response = new Response(200, [
                    'Content-Type' => 'application/xml; charset=utf-8',
                ], $wsdl);
                $connection->send($response);
                return;
            }

            $server = new SoapServer('/var/www/interfacems/workman/webman.wsdl', array('soap_version' => SOAP_1_2));
            $server->setClass('SoapServ');
            ob_start();
            $server->handle();
            // readfile('webman.wsdl');
            $ret = ob_get_clean();
            $response = new Response(200, [
                'Content-Type' => 'text/xml; charset=utf-8',
            ], $ret);

            $connection->send($response);
            return;
        } catch (Exception $e) {
            // 錯誤處理邏輯
            $connection->send("Error: " . $e->getMessage());
        }
    } elseif ($request->path() == '/client') {
        try {
            $client = new SoapClient("http://localhost:8080/serv?wsdl");
            $fs = $client->__getFunctions();
            // 向?yàn)g覽器發(fā)送hello world
            $response = new Response(200, [
                'Content-Type' => 'text/json; charset=utf-8',
            ], json_encode($fs, JSON_UNESCAPED_UNICODE));
            $connection->send($response);
        } catch (Exception $e) {
            // 錯誤處理邏輯
            $connection->send("Error: " . $e->getMessage());
        }
    } else {
        // 如果不是預(yù)期的路徑,可以發(fā)送404響應(yīng)或其他邏輯
        $connection->send("Not Found");
    }
};

// 運(yùn)行worker
Worker::runAll();
  • 暫無評論
年代過于久遠(yuǎn),無法發(fā)表回答
??