• <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應用程序,甚至跨平臺也不是問題。但是,諸如stockweatherexchange這些應用都是面向大眾提供的免費資源,不是企業級的應用,絕大多數都不需要用戶認證。而那些商業化的應用卻恰恰相反,大部分都要求客戶端提供這樣那樣的驗證。

             

            由于有認證的免費資源實在難找,我只好把公司正在使用的一個服務的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客戶端和服務端。客戶端與前幾節的相比,首先是增加了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

            日本久久久久久中文字幕| 日日狠狠久久偷偷色综合96蜜桃| 久久精品成人免费观看97| 久久久久国色AV免费观看| 香蕉久久夜色精品国产2020| 久久青青色综合| 99久久精品国内| 久久人人爽人人爽人人片AV麻豆| 久久九九兔免费精品6| 国产精品视频久久| 久久无码AV中文出轨人妻| 久久精品无码一区二区无码| 久久人人爽人人爽人人片AV东京热| 亚洲欧美成人综合久久久| 93精91精品国产综合久久香蕉| 亚洲综合伊人久久综合| 久久九九久精品国产| 丁香狠狠色婷婷久久综合| 狠狠色狠狠色综合久久| 久久久久国产一区二区三区| 久久久久久a亚洲欧洲aⅴ| 亚洲国产欧美国产综合久久| 精品国产青草久久久久福利| 97热久久免费频精品99| 国内精品人妻无码久久久影院导航| 开心久久婷婷综合中文字幕| 久久香蕉国产线看观看99| 99久久成人国产精品免费| 久久天天躁狠狠躁夜夜躁2O2O| 久久久久久国产精品无码下载| 久久久久久毛片免费看| 狠狠精品久久久无码中文字幕 | 久久久久久久精品妇女99| 久久av免费天堂小草播放| 久久这里只精品国产99热| 久久99国产亚洲高清观看首页| 久久综合九色综合网站| 久久精品人成免费| 久久青草国产精品一区| 久久青青草原精品影院| 久久九九久精品国产|