• <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++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

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

             

            由于有認證的免費資源實在難找,我只好把公司正在使用的一個服務的wsdl裁剪一下,拿到這里作為實例,裁剪后的wsdl只保留一個echo接口,顧名思義,就是客戶端送什么字符串上來,服務端就返回同樣的字符串。這個wsdl如下(業(yè)務相關的網(wǎng)址和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,按照前幾節(jié)的方法分別建立gSOAP客戶端和服務端??蛻舳伺c前幾節(jié)的相比,首先是增加了soap­_ssl_client_context處理HTTPS協(xié)議。其次,本案例使用的是基本認證(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參數(shù),以及需要鏈接libssl庫。

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

             

            服務端的編寫相對麻煩,以下給出一個最簡單的實現(xiàn)。與第二節(jié)的stock服務端程序相比,主要是增加了soap_ssl_server_context處理HTTPS協(xié)議,其中需要用到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里已經(jīng)指定默認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日,在此之后執(zhí)行的結果可能會不一樣。


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

            亚洲一级Av无码毛片久久精品| 久久无码人妻一区二区三区午夜 | 久久精品国产99国产电影网| 久久综合一区二区无码| 久久综合伊人77777麻豆| 久久亚洲国产午夜精品理论片 | 亚洲国产成人久久精品影视| 国产精品美女久久久m| 九九久久99综合一区二区| 精品久久久久久成人AV| 热99re久久国超精品首页| 热久久国产精品| 国产精品伊人久久伊人电影| 岛国搬运www久久| 久久中文字幕视频、最近更新| 久久亚洲精品无码aⅴ大香| 中文字幕亚洲综合久久菠萝蜜| 亚洲香蕉网久久综合影视| 国产成人精品综合久久久| 久久久久久亚洲AV无码专区| 国产精品岛国久久久久| 久久免费大片| 一本久久知道综合久久| 国产精品久久国产精麻豆99网站 | 国产精品视频久久久| 婷婷综合久久中文字幕| 日韩欧美亚洲综合久久影院Ds| 久久久久亚洲AV无码永不| 777米奇久久最新地址| 久久se精品一区精品二区国产| 国内高清久久久久久| 免费国产99久久久香蕉| 国产精品久久久久蜜芽| 99久久无色码中文字幕| 无码人妻少妇久久中文字幕| 99久久成人18免费网站| 2021国产精品久久精品| 久久久久久久综合日本亚洲| 伊人久久无码精品中文字幕| 欧美一区二区精品久久| 亚洲精品高清国产一线久久|