• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            The power of C, the power of MD

            A problem is a chance to do your best
            posts - 11, comments - 22, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            經過前幾節的講解,相信大家都能夠熟練地開發gSOAP應用程序,甚至跨平臺也不是問題。但是,諸如stockweather、exchange這些應用都是面向大眾提供的免費資源,不是企業級的應用,絕大多數都不需要用戶認證。而那些商業化的應用卻恰恰相反,大部分都要求客戶端提供這樣那樣的驗證。

             

            由于有認證的免費資源實在難找,我只好把公司正在使用的一個服務的wsdl裁剪一下,拿到這里作為實例,裁剪后的wsdl只保留一個echo接口,顧名思義,就是客戶端送什么字符串上來,服務端就返回同樣的字符串。這個wsdl如下(業務相關的網址和end point均已作了特別處理):

            <?xml version='1.0' encoding='UTF-8'?>
            <s0:definitions name="ServicesDefinitions" targetNamespace="http://echo.rsecure.com/ECHO" xmlns="" xmlns:s0="http://schemas.xmlsoap.org/wsdl/" xmlns:s1="http://echo.rsecure.com/ECHO" xmlns:s2="http://schemas.xmlsoap.org/wsdl/soap/">
              
            <s0:types>
                
            <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://echo.rsecure.com/ECHO" xmlns:s0="http://schemas.xmlsoap.org/wsdl/" xmlns:s1="http://echo.rsecure.com/ECHO" xmlns:s2="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
                  
            <xs:element name="echo">
                    
            <xs:complexType>
                      
            <xs:sequence>
                        
            <xs:element name="EchoMessage" type="xs:string"/>
                      
            </xs:sequence>
                    
            </xs:complexType>
                  
            </xs:element>
                  
            <xs:element name="echoResponse">
                    
            <xs:complexType>
                      
            <xs:sequence>
                        
            <xs:element name="Echo" type="xs:string"/>
                      
            </xs:sequence>
                    
            </xs:complexType>
                  
            </xs:element>
                
            </xs:schema>
              
            </s0:types>
              
            <s0:message name="echo">
                
            <s0:part element="s1:echo" name="parameters"/>
              
            </s0:message>
              
            <s0:message name="echoResponse">
                
            <s0:part element="s1:echoResponse" name="Echo"/>
              
            </s0:message>
              
            <s0:portType name="LMIAPort">
                
            <s0:operation name="echo" parameterOrder="parameters">
                  
            <s0:input message="s1:echo"/>
                  
            <s0:output message="s1:echoResponse"/>
                
            </s0:operation>
              
            </s0:portType>
              
            <s0:binding name="ServicesSoapBinding" type="s1:LMIAPort">
                
            <s2:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
                
            <s0:operation name="echo">
                  
            <s2:operation style="document"/>
                  
            <s0:input>
                    
            <s2:body parts="parameters" use="literal"/>
                  
            </s0:input>
                  
            <s0:output>
                    
            <s2:body parts="Echo" use="literal"/>
                  
            </s0:output>
                
            </s0:operation>
              
            </s0:binding>
              
            <s0:service name="Services">
                
            <s0:port binding="s1:ServicesSoapBinding" name="lmiAPort">
                  
            <s2:address location="https://localhost:6883"/>
                
            </s0:port>
              
            </s0:service>
            </s0:definitions>

             

            gsoap-2.7/gsoap/wsdl/目錄下建立兩個目錄:echoecho_server,按照前幾節的方法分別建立gSOAP客戶端和服務端??蛻舳伺c前幾節的相比,首先是增加了soap­_ssl_client_context處理HTTPS協議。其次,本案例使用的是基本認證(Basic Authentication),需要在soap變量初始化之后給出用戶名和密碼。

                    struct soap soap;
                    soap_init(
            &soap);
                    soap.userid 
            = argv[1];
                    soap.passwd 
            = argv[2];
             

            客戶端完整程序如下:

            #include "soapH.h"
            #include 
            "ServicesSoapBinding.nsmap"

            int main(int argc, char **argv) {
                    
            if ( argc != 4 && argc != 5 ) {
                            printf(
            "Usage: %s username password message [end_point]\n", argv[0]);
                            exit(
            -1);
                    }

                    
            struct soap soap;
                    soap_init(
            &soap);
                    soap.userid 
            = argv[1];
                    soap.passwd 
            = argv[2];

                    
            struct _ns1__echo request;
                    
            struct _ns1__echoResponse response;

                    soap_ssl_init();
                    
            if ( soap_ssl_client_context(&soap, SOAP_SSL_NO_AUTHENTICATION, NULL, NULL, NULL, NULL, NULL) ) {
                            soap_print_fault(
            &soap, stderr);
                            exit(
            -1);
                    }

                    request.EchoMessage 
            = argv[3];
                    
            char *endpoint = NULL;
                    
            if ( argc == 5 )
                            endpoint 
            = argv[4];

                    printf(
            "username  : %s\n", soap.userid);
                    printf(
            "password  : %s\n", soap.passwd);
                    printf(
            "message   : %s\n", request.EchoMessage);
                    
            if ( endpoint )
                            printf(
            "end point : %s\n", endpoint);

                    
            if ( soap_call___ns1__echo(&soap, endpoint, NULL, &request, &response) == SOAP_OK ) {
                            printf(
            "%s\n", response.Echo);
                    }
                    
            else {
                            soap_print_fault(
            &soap, stderr);
                    }

                    soap_destroy(
            &soap);
                    soap_end(
            &soap);
                    soap_done(
            &soap);
                    
            return 0;
            }

             

            保存為echo.c,編譯命令如下,注意增加了-DWITH_OPENSSL參數,以及需要鏈接libssl庫。

            gcc -DWITH_OPENSSL -O2 -o echo echo.c soapC.c soapClient.c ../../stdsoap2.c -I../.. -L../.. -lgsoap –lssl

             

            服務端的編寫相對麻煩,以下給出一個最簡單的實現。與第二節的stock服務端程序相比,主要是增加了soap_ssl_server_context處理HTTPS協議,其中需要用到gsoap-2.7.17自帶的ssl實例程序中的幾個pem證書,把它們拷貝過來即可使用。另外,與不需要認證的應用相比,__ns1__echo增加了用戶密碼校驗。這個案例里,設定客戶端送上來的用戶/密碼應當為roy/liang,否則將返回401錯誤。

            #include <pthread.h>

            #include 
            "soapH.h"
            #include 
            "ServicesSoapBinding.nsmap"

            void *process_request(void *soap) {
                    pthread_detach(pthread_self());
                    
            if ( soap_ssl_accept((struct soap *) soap) != SOAP_OK )
                            soap_print_fault((
            struct soap *) soap, stderr);
                    
            else
                            soap_serve((
            struct soap *) soap);
                    soap_end((
            struct soap *) soap);
                    soap_free((
            struct soap *) soap);
                    
            return NULL;
            }

            int main(int argc, char **argv) {
                    
            if ( argc != 2 ) {
                            printf(
            "Usage: %s port\n", argv[0]);
                            exit(
            -1);
                    }
                    
            int port = atol(argv[1]);

                    pthread_t tid;
                    
            struct soap *tsoap;
                    
            struct soap soap;
                    soap_init(
            &soap);

                    soap_ssl_init();
                    
            if ( soap_ssl_server_context(&soap, SOAP_SSL_DEFAULT, "server.pem""password""cacert.pem", NULL, "dh512.pem", NULL, argv[0]) ) {
                            soap_print_fault(
            &soap, stderr);
                            exit(
            -1);
                    }

                    
            int m, s;
                    
            if ( (m = soap_bind(&soap, NULL, port, 100)) < 0 ) {
                            soap_print_fault(
            &soap, stderr);
                    }
                    
            else {
                            printf(
            "Socket connect successfully: master socket = %d\n", m);
                            
            int i = 0;
                            
            while ( 1 ) {
                                    
            if ( (s = soap_accept(&soap)) < 0 ) {
                                            soap_print_fault(
            &soap, stderr);
                                            
            break;
                                    }
                                    printf(
            "Connection %d accepted from IP = %d.%d.%d.%d, slave socket = %d\n"++i, (soap.ip >> 24& 0xff, (soap.ip >> 16& 0xff, (soap.ip >> 8& 0xff, soap.ip & 0xff, s);
                                    tsoap 
            = soap_copy(&soap);
                                    
            if ( !tsoap ) {
                                            soap_closesock(
            &soap);
                                            
            continue;
                                    }
                                    pthread_create(
            &tid, NULL, &process_request, (void *) tsoap);
                            }
                    }
                    soap_done(
            &soap);
                    
            return 0;
            }

            int __ns1__echo(
                    
            struct soap *soap,
                    
            struct _ns1__echo *request,
                    
            struct _ns1__echoResponse *response) {
                    
            if ( !soap->userid || !soap->passwd || strcmp(soap->userid, "roy"|| strcmp(soap->passwd, "liang") )
                            
            return 401;
                    
            int len = strlen(request->EchoMessage);
                    response
            ->Echo = (char *) malloc(sizeof(char* (len + 1));
                    strcpy(response
            ->Echo, request->EchoMessage);
                    
            return SOAP_OK;
            }

             

             

            保存為echo_server.c,編譯命令是:

            gcc -DWITH_OPENSSL -O2 -o echo_server echo_server.c soapC.c soapServer.c ../../stdsoap2.c -I../.. -L../.. -lgsoap -lssl -lcrypto –lpthread

             

            客戶端和服務端都編譯完成后,首先啟動服務端:

            -bash-3.2$ ./echo_server 6883

            Socket connect successfully: master socket = 3

             

            然后,在另一個窗口運行客戶端,由于wsdl里已經指定默認end pointhttps://localhost:6883,因此,客戶端并不需要額外給出。

             

            正常的返回結果:

            -bash-3.2$ ./echo roy liang hi
            username  : roy
            password  : liang
            message   : hi
            hi

             

            用戶、密碼不正確將返回401錯誤:

            -bash-3.2$ ./echo roy xxx hi
            username  : roy
            password  : xxx
            message   : hi
            Error 401 fault: SOAP-ENV:Server [no subcode]
            "HTTP/1.1 401 Unauthorized"
            Detail: <?xml version="1.0" encoding="UTF-8"?>
            <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://echo.rsecure.com/ECHO"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Client</faultcode><faultstring>HTTP Error: 401 Unauthorized</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>

             

            基于HTTP的基本認證(Basic Authentication)比基于HTTPS的更加簡單,在客戶端和服務端的程序去除HTTPS處理即可,不再贅述。

             

            另外,本案例中用到的證書的失效日期好像是2010112日,在此之后執行的結果可能會不一樣。


            http://blog.csdn.net/yui/archive/2010/08/17/5817771.aspx

            久久天天躁夜夜躁狠狠躁2022| 97精品国产91久久久久久| 久久精品成人影院| 一级做a爰片久久毛片免费陪| 久久久久久精品免费看SSS| 蜜臀久久99精品久久久久久小说| 狠狠干狠狠久久| 久久久久久伊人高潮影院| 久久久久久狠狠丁香| 久久久久久伊人高潮影院| 99久久国产热无码精品免费久久久久| 久久亚洲中文字幕精品一区| 日产精品久久久久久久| 久久不见久久见免费影院www日本| 久久综合久久综合亚洲| 91精品免费久久久久久久久| 久久天天躁夜夜躁狠狠| 久久青青国产| 久久电影网2021| 久久国产亚洲精品无码| 亚洲国产成人精品无码久久久久久综合| 亚洲国产欧洲综合997久久| 久久久久亚洲av毛片大| 青青草原综合久久大伊人精品| 久久无码高潮喷水| 亚洲精品高清一二区久久| 国内精品久久久久久久久| 2020久久精品国产免费| 婷婷久久久亚洲欧洲日产国码AV| 人妻无码精品久久亚瑟影视| 国产精品成人99久久久久| 美女写真久久影院| 色综合久久天天综合| 久久国产精品成人免费| 久久精品一区二区| 亚洲国产成人久久精品影视| 国产精品美女久久久m| 97精品伊人久久大香线蕉app| 亚洲中文字幕无码久久2017| 久久永久免费人妻精品下载| 一本色道久久综合亚洲精品|