A simple web service over HTTP library. Calls a HTTP server via GET, and returns the response wrapped in a XML parser. All calls are synchronous. Needs the NetServicesMin, DNSResolver, TcpLineStream and spxml libraries. The code for URL handling has been copied directly from the original NetServices library (Thanks to Donatien!).

Revision:
1:62e112d14c8f
Parent:
0:5e8527b638e1
Child:
2:687430e7f63a
--- a/webservice.cpp	Tue Jan 11 23:00:09 2011 +0000
+++ b/webservice.cpp	Sat Jan 29 23:29:41 2011 +0000
@@ -1,200 +1,61 @@
-#include "Timer.h"
-
-#include "webservice.h"
-
-#include "spxmlnode.hpp"
-#include "spxmlhandle.hpp"
-
-#include "dnsresolve.h"
-
-void WebService::onTCPSocketEvent(TCPSocketEvent e) {
-//    printf("New TCPSocketEvent: %d\n",e);
-    switch (e) {
-        case TCPSOCKET_CONNECTED:
-            _connected = true;
-            _connecting=false;
-            break;
-
-        case TCPSOCKET_READABLE:
-            break;
-        case TCPSOCKET_WRITEABLE:
-            break;
-
-        case TCPSOCKET_CONTIMEOUT:
-        case TCPSOCKET_CONRST:
-        case TCPSOCKET_CONABRT:
-        case TCPSOCKET_ERROR:
-        case TCPSOCKET_DISCONNECTED: {
-            // don't close the real socket here, as this may skip the already received data
-            _connected = false;
-            _connecting=false;
-        }
-        break;
-    }
-}
-
-WebService::WebService(const char* url):_url(url) {
-    _closed=false;
-    _readpos=0;
-    _readlen=0;
-    _readpos=0;
-    _readlen=0;
-
-    _socket.setOnEvent(this,&WebService::onTCPSocketEvent);
-}
-
-SP_XmlDomParser* WebService::callService() {
-    Url url;
-    url.fromString(_url);
-
-    string request=string("GET ").append(_url).append(" HTTP/1.0\r\n\r\n");
-
-    IpAddr addr;
-    if (!url.getHostIp(&addr)) {
-        DNSResolver dr;
-        addr=dr.resolveName(url.getHost().c_str());
-    }
-//    printf("host ip=%i.%i.%i.%i\n",addr[0],addr[1],addr[2],addr[3]);
-
-    int port=0==url.getPort()?80:url.getPort();
-
-    Host host(addr, port);
-
-    TCPSocketErr bindErr = _socket.connect(host);
-
-    if (bindErr != 0) {
-        printf("connection error %i\n", bindErr);
-        return false;
-    }
-
-    // wait for connection established
-    _connecting=true;
-    mbed::Timer tmr;
-    tmr.start();
-
-    while (_connecting) {
-        Net::poll();
-        wait(0.1);
-        if (tmr.read()>10) {
-            printf("reached timeout\n");
-            break;
-        }
-    }
-
-    if (!_connected) {
-        printf("error - could not connect (timeout)\n");
-        return NULL;
-    }
-//    printf("send request[%s]\n",request.c_str());
-    _socket.send(request.c_str(),request.length());
-    Net::poll();
-
-    if (!_connected)
-        return NULL;
-
-    string firstLine=readResponseLine();
-    // todo: parse for HTTP response
-    // response must be for HTTP/1.0, and be 200
-    if (0!=firstLine.compare("HTTP/1.0 200 OK"))
-    {
-        printf("call not sucessfull, response=%s\n",firstLine.c_str());
-        return NULL;
-    }    
-    // skip headers    
-    while (true) {
-        string line=readResponseLine();
-//        printf("header=[%s]\n",line.c_str());
-        if (0==line.length())
-            break;
-    }
-    SP_XmlDomParser *parser=new SP_XmlDomParser();
-    while (true) {
-        string line=readResponseLine();
-//        printf("content=[%s]\n",line.c_str());
-        parser->append(line.c_str(),line.length());
-        if (0==line.length())
-            break;
-    }
-
-    return parser;
-}
-
-void WebService::close() {
-    if (_closed)
-        return;
-
-    while (_connected) {
-        Net::poll();
-        // read remaining data
-        int err=_socket.recv(_readbuf,BUFSIZE-1);
-        if (err<=0)
-            break;
-    }
-
-    while (true) {
-        Net::poll();
-        // read remaining data
-        int err=_socket.recv(_readbuf,BUFSIZE-1);
-        if (err<=0)
-            break;
-    }
-
-    _socket.resetOnEvent();
-    _socket.close();
-
-    _closed=true;
-}
-
-
-
-string WebService::readResponseLine() {
-    string r;
-    bool got_r=false;
-    
-    int emptyCount=0;
-    while (true) {
-        Net::poll();
-        if (_readlen>_readpos) {
-            while (_readbuf[_readpos]!=0 && _readpos<_readlen) {
-                char c=_readbuf[_readpos++];
-                if (!got_r) {
-                    if (c=='\r') {
-                        got_r=true;
-                    } else {
-                        r.push_back(c);
-                    }
-                } else {
-                    if (c=='\n') {
-                        return r;
-                    } else {
-                        r.push_back('\r'); // push missed \r also, so push it to string
-                        r.push_back(c);
-                        got_r=false;
-                    }
-                }
-            }
-        } else {
-            int err=_socket.recv(_readbuf,BUFSIZE-1);
-            if (err < 0) {
-                printf("error while receiving data: %i!\n",err);
-                break;
-            } else if (err>0) {
-                emptyCount=0;
-                _readbuf[err]=0;
-                _readlen=err;
-                _readpos=0;
-//                printf("r=%s\n",_readbuf);
-            }
-            else
-            {
-                // when we don't receive any data, and are not connected
-                // we stop because there isn't anything left
-                if (emptyCount++>2)
-                    if (!_connected)
-                        break;
-            }
-        }
-        wait(0.1);
-    }
-    return r;
-}
\ No newline at end of file
+#include "Timer.h"
+
+#include "webservice.h"
+
+#include "spxmlnode.hpp"
+#include "spxmlhandle.hpp"
+
+WebService::WebService(const char* urlStr) {
+    Url *url=new Url();
+    url->fromString(urlStr);
+    
+//    printf("host name from URL=%s\n",url->getHost().c_str());
+
+    _stream=new TCPLineStream(url->getHost().c_str(),0==url->getPort()?80:url->getPort(),"\r\n");
+    delete url;
+
+    _request=string("GET ").append(urlStr).append(" HTTP/1.0\r\n");
+//    printf("request=[%s]\n",_request.c_str());
+}
+
+SP_XmlDomParser* WebService::callService() {
+    if (!_stream->open())
+        return NULL;
+
+//    printf("send request[%s]\n",request.c_str());
+    _stream->sendLine(_request);
+
+    string firstLine=_stream->readLine();
+    // todo: parse for HTTP response
+    // response must be for HTTP/1.0, and be 200
+    if (0!=firstLine.compare("HTTP/1.0 200 OK")) {
+        printf("call not sucessfull, response=%s\n",firstLine.c_str());
+        return NULL;
+    }
+    // skip headers
+    while (true) {
+        string line=_stream->readLine();
+//        printf("header=[%s]\n",line.c_str());
+        if (0==line.length())
+            break;
+    }
+    SP_XmlDomParser *parser=new SP_XmlDomParser();
+    while (true) {
+        string line=_stream->readLine(1500);
+//        printf("content=[%s]\n",line.c_str());
+        parser->append(line.c_str(),line.length());
+        if (0==line.length())
+            break;
+    }
+    _stream->close();
+    return parser;
+}
+
+void WebService::close() {
+    if (NULL!=_stream) {
+        _stream->close();
+        delete _stream;
+        _stream=NULL;
+    }
+}
+