diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2009-03-23 09:18:55 (GMT) |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-03-23 09:18:55 (GMT) |
commit | e5fcad302d86d316390c6b0f62759a067313e8a9 (patch) | |
tree | c2afbf6f1066b6ce261f14341cf6d310e5595bc1 /tests/auto/qhttp | |
download | Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.zip Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.gz Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.bz2 |
Long live Qt 4.5!
Diffstat (limited to 'tests/auto/qhttp')
-rw-r--r-- | tests/auto/qhttp/.gitattributes | 1 | ||||
-rw-r--r-- | tests/auto/qhttp/.gitignore | 1 | ||||
-rw-r--r-- | tests/auto/qhttp/dummyserver.h | 114 | ||||
-rw-r--r-- | tests/auto/qhttp/qhttp.pro | 18 | ||||
-rw-r--r-- | tests/auto/qhttp/rfc3252.txt | 899 | ||||
-rw-r--r-- | tests/auto/qhttp/trolltech | 8 | ||||
-rw-r--r-- | tests/auto/qhttp/tst_qhttp.cpp | 1530 | ||||
-rwxr-xr-x | tests/auto/qhttp/webserver/cgi-bin/retrieve_testfile.cgi | 6 | ||||
-rwxr-xr-x | tests/auto/qhttp/webserver/cgi-bin/rfc.cgi | 5 | ||||
-rwxr-xr-x | tests/auto/qhttp/webserver/cgi-bin/store_testfile.cgi | 6 | ||||
-rw-r--r-- | tests/auto/qhttp/webserver/index.html | 899 | ||||
-rw-r--r-- | tests/auto/qhttp/webserver/rfc3252 | 899 | ||||
-rw-r--r-- | tests/auto/qhttp/webserver/rfc3252.txt | 899 |
13 files changed, 5285 insertions, 0 deletions
diff --git a/tests/auto/qhttp/.gitattributes b/tests/auto/qhttp/.gitattributes new file mode 100644 index 0000000..e04709a --- /dev/null +++ b/tests/auto/qhttp/.gitattributes @@ -0,0 +1 @@ +rfc3252.txt -crlf diff --git a/tests/auto/qhttp/.gitignore b/tests/auto/qhttp/.gitignore new file mode 100644 index 0000000..00c1f49 --- /dev/null +++ b/tests/auto/qhttp/.gitignore @@ -0,0 +1 @@ +tst_qhttp diff --git a/tests/auto/qhttp/dummyserver.h b/tests/auto/qhttp/dummyserver.h new file mode 100644 index 0000000..fe883c7 --- /dev/null +++ b/tests/auto/qhttp/dummyserver.h @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ +// Use if you need + +class DummyHttpServer : public QTcpServer +{ + Q_OBJECT +public: + DummyHttpServer() : phase(Header) + { listen(); } + +protected: + enum { + Header, + Data1, + Data2, + Close + } phase; + void incomingConnection(int socketDescriptor) + { + QSslSocket *socket = new QSslSocket(this); + socket->setSocketDescriptor(socketDescriptor, QAbstractSocket::ConnectedState); + socket->ignoreSslErrors(); + socket->startServerEncryption(); + connect(socket, SIGNAL(readyRead()), SLOT(handleReadyRead())); + } + +public slots: + void handleReadyRead() + { + QTcpSocket *socket = static_cast<QTcpSocket *>(sender()); + socket->readAll(); + if (phase != Header) + return; + + phase = Data1; + static const char header[] = + "HTTP/1.0 200 OK\r\n" + "Date: Fri, 07 Sep 2007 12:33:18 GMT\r\n" + "Server: Apache\r\n" + "Expires:\r\n" + "Cache-Control:\r\n" + "Pragma:\r\n" + "Last-Modified: Thu, 06 Sep 2007 08:52:06 +0000\r\n" + "Etag: a700f59a6ccb1ad39af68d998aa36fb1\r\n" + "Vary: Accept-Encoding\r\n" + "Content-Length: 6560\r\n" + "Connection: close\r\n" + "Content-Type: text/html; charset=utf-8\r\n" + "\r\n"; + + + socket->write(header, sizeof header - 1); + connect(socket, SIGNAL(bytesWritten(qint64)), SLOT(handleBytesWritten()), Qt::QueuedConnection); + } + + void handleBytesWritten() + { + QTcpSocket *socket = static_cast<QTcpSocket *>(sender()); + if (socket->bytesToWrite() != 0) + return; + + if (phase == Data1) { + QByteArray data(4096, 'a'); + socket->write(data); + phase = Data2; + } else if (phase == Data2) { + QByteArray data(2464, 'a'); + socket->write(data); + phase = Close; + } else { + //socket->disconnectFromHost(); + //socket->deleteLater(); + } + } +}; diff --git a/tests/auto/qhttp/qhttp.pro b/tests/auto/qhttp/qhttp.pro new file mode 100644 index 0000000..9186140 --- /dev/null +++ b/tests/auto/qhttp/qhttp.pro @@ -0,0 +1,18 @@ +load(qttest_p4) +SOURCES += tst_qhttp.cpp + + +QT = core network + +wince*: { + webFiles.sources = webserver/* + webFiles.path = webserver + cgi.sources = webserver/cgi-bin/* + cgi.path = webserver/cgi-bin + addFiles.sources = rfc3252.txt trolltech + addFiles.path = . + DEPLOYMENT = addFiles webFiles cgi + DEFINES += SRCDIR=\\\"\\\" +} else { + DEFINES += SRCDIR=\\\"$$PWD/\\\" +} diff --git a/tests/auto/qhttp/rfc3252.txt b/tests/auto/qhttp/rfc3252.txt new file mode 100644 index 0000000..b80c61b --- /dev/null +++ b/tests/auto/qhttp/rfc3252.txt @@ -0,0 +1,899 @@ + + + + + + +Network Working Group H. Kennedy +Request for Comments: 3252 Mimezine +Category: Informational 1 April 2002 + + + Binary Lexical Octet Ad-hoc Transport + +Status of this Memo + + This memo provides information for the Internet community. It does + not specify an Internet standard of any kind. Distribution of this + memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2002). All Rights Reserved. + +Abstract + + This document defines a reformulation of IP and two transport layer + protocols (TCP and UDP) as XML applications. + +1. Introduction + +1.1. Overview + + This document describes the Binary Lexical Octet Ad-hoc Transport + (BLOAT): a reformulation of a widely-deployed network-layer protocol + (IP [RFC791]), and two associated transport layer protocols (TCP + [RFC793] and UDP [RFC768]) as XML [XML] applications. It also + describes methods for transporting BLOAT over Ethernet and IEEE 802 + networks as well as encapsulating BLOAT in IP for gatewaying BLOAT + across the public Internet. + +1.2. Motivation + + The wild popularity of XML as a basis for application-level protocols + such as the Blocks Extensible Exchange Protocol [RFC3080], the Simple + Object Access Protocol [SOAP], and Jabber [JABBER] prompted + investigation into the possibility of extending the use of XML in the + protocol stack. Using XML at both the transport and network layer in + addition to the application layer would provide for an amazing amount + of power and flexibility while removing dependencies on proprietary + and hard-to-understand binary protocols. This protocol unification + would also allow applications to use a single XML parser for all + aspects of their operation, eliminating developer time spent figuring + out the intricacies of each new protocol, and moving the hard work of + + + + +Kennedy Informational [Page 1] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + parsing to the XML toolset. The use of XML also mitigates concerns + over "network vs. host" byte ordering which is at the root of many + network application bugs. + +1.3. Relation to Existing Protocols + + The reformulations specified in this RFC follow as closely as + possible the spirit of the RFCs on which they are based, and so MAY + contain elements or attributes that would not be needed in a pure + reworking (e.g. length attributes, which are implicit in XML.) + + The layering of network and transport protocols are maintained in + this RFC despite the optimizations that could be made if the line + were somewhat blurred (i.e. merging TCP and IP into a single, larger + element in the DTD) in order to foster future use of this protocol as + a basis for reformulating other protocols (such as ICMP.) + + Other than the encoding, the behavioral aspects of each of the + existing protocols remain unchanged. Routing, address spaces, TCP + congestion control, etc. behave as specified in the extant standards. + Adapting to new standards and experimental algorithm heuristics for + improving performance will become much easier once the move to BLOAT + has been completed. + +1.4. Requirement Levels + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in BCP 14, RFC 2119 + [RFC2119]. + +2. IPoXML + + This protocol MUST be implemented to be compliant with this RFC. + IPoXML is the root protocol REQUIRED for effective use of TCPoXML + (section 3.) and higher-level application protocols. + + The DTD for this document type can be found in section 7.1. + + The routing of IPoXML can be easily implemented on hosts with an XML + parser, as the regular structure lends itself handily to parsing and + validation of the document/datagram and then processing the + destination address, TTL, and checksum before sending it on to its + next-hop. + + The reformulation of IPv4 was chosen over IPv6 [RFC2460] due to the + wider deployment of IPv4 and the fact that implementing IPv6 as XML + would have exceeded the 1500 byte Ethernet MTU. + + + +Kennedy Informational [Page 2] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + All BLOAT implementations MUST use - and specify - the UTF-8 encoding + of RFC 2279 [RFC2279]. All BLOAT document/datagrams MUST be well- + formed and include the XMLDecl. + +2.1. IP Description + + A number of items have changed (for the better) from the original IP + specification. Bit-masks, where present have been converted into + human-readable values. IP addresses are listed in their dotted- + decimal notation [RFC1123]. Length and checksum values are present + as decimal integers. + + To calculate the length and checksum fields of the IP element, a + canonicalized form of the element MUST be used. The canonical form + SHALL have no whitespace (including newline characters) between + elements and only one space character between attributes. There + SHALL NOT be a space following the last attribute in an element. + + An iterative method SHOULD be used to calculate checksums, as the + length field will vary based on the size of the checksum. + + The payload element bears special attention. Due to the character + set restrictions of XML, the payload of IP datagrams (which MAY + contain arbitrary data) MUST be encoded for transport. This RFC + REQUIRES the contents of the payload to be encoded in the base-64 + encoding of RFC 2045 [RFC2045], but removes the requirement that the + encoded output MUST be wrapped on 76-character lines. + + + + + + + + + + + + + + + + + + + + + + + + +Kennedy Informational [Page 3] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +2.2. Example Datagram + + The following is an example IPoXML datagram with an empty payload: + + <?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE ip PUBLIC "-//IETF//DTD BLOAT 1.0 IP//EN" "bloat.dtd"> + <ip> + <header length="474"> + <version value="4"/> + <tos precedence="Routine" delay="Normal" throughput="Normal" + relibility="Normal" reserved="0"/> + <total.length value="461"/> + <id value="1"/> + <flags reserved="0" df="dont" mf="last"/> + <offset value="0"/> + <ttl value="255"/> + <protocol value="6"/> + <checksum value="8707"/> + <source address="10.0.0.22"/> + <destination address="10.0.0.1"/> + <options> + <end copied="0" class="0" number="0"/> + </options> + <padding pad="0"/> + </header> + <payload> + </payload> + </ip> + +3. TCPoXML + + This protocol MUST be implemented to be compliant with this RFC. The + DTD for this document type can be found in section 7.2. + +3.1. TCP Description + + A number of items have changed from the original TCP specification. + Bit-masks, where present have been converted into human-readable + values. Length and checksum and port values are present as decimal + integers. + + To calculate the length and checksum fields of the TCP element, a + canonicalized form of the element MUST be used as in section 2.1. + + An iterative method SHOULD be used to calculate checksums as in + section 2.1. + + The payload element MUST be encoded as in section 2.1. + + + +Kennedy Informational [Page 4] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + The TCP offset element was expanded to a maximum of 255 from 16 to + allow for the increased size of the header in XML. + + TCPoXML datagrams encapsulated by IPoXML MAY omit the <?xml?> header + as well as the <!DOCTYPE> declaration. + +3.2. Example Datagram + + The following is an example TCPoXML datagram with an empty payload: + + <?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE tcp PUBLIC "-//IETF//DTD BLOAT 1.0 TCP//EN" "bloat.dtd"> + <tcp> + <tcp.header> + <src port="31415"/> + <dest port="42424"/> + <sequence number="322622954"/> + <acknowledgement number="689715995"/> + <offset number=""/> + <reserved value="0"/> + <control syn="1" ack="1"/> + <window size="1"/> + <urgent pointer="0"/> + <checksum value="2988"/> + <tcp.options> + <tcp.end kind="0"/> + </tcp.options> + <padding pad="0"/> + </tcp.header> + <payload> + </payload> + </tcp> + +4. UDPoXML + + This protocol MUST be implemented to be compliant with this RFC. The + DTD for this document type can be found in section 7.3. + +4.1. UDP Description + + A number of items have changed from the original UDP specification. + Bit-masks, where present have been converted into human-readable + values. Length and checksum and port values are present as decimal + integers. + + + + + + + +Kennedy Informational [Page 5] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + To calculate the length and checksum fields of the UDP element, a + canonicalized form of the element MUST be used as in section 2.1. An + iterative method SHOULD be used to calculate checksums as in section + 2.1. + + The payload element MUST be encoded as in section 2.1. + + UDPoXML datagrams encapsulated by IPoXML MAY omit the <?xml?> header + as well as the <!DOCTYPE> declaration. + +4.2. Example Datagram + + The following is an example UDPoXML datagram with an empty payload: + + <?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE udp PUBLIC "-//IETF//DTD BLOAT 1.0 UDP//EN" "bloat.dtd"> + <udp> + <udp.header> + <src port="31415"/> + <dest port="42424"/> + <udp.length value="143"/> + <checksum value="2988"/> + </udp.header> + <payload> + </payload> + </udp> + +5. Network Transport + + This document provides for the transmission of BLOAT datagrams over + two common families of physical layer transport. Future RFCs will + address additional transports as routing vendors catch up to the + specification, and we begin to see BLOAT routed across the Internet + backbone. + +5.1. Ethernet + + BLOAT is encapsulated in Ethernet datagrams as in [RFC894] with the + exception that the type field of the Ethernet frame MUST contain the + value 0xBEEF. The first 5 octets of the Ethernet frame payload will + be 0x3c 3f 78 6d 6c ("<?xml".) + +5.2. IEEE 802 + + BLOAT is encapsulated in IEEE 802 Networks as in [RFC1042] except + that the protocol type code for IPoXML is 0xBEEF. + + + + + +Kennedy Informational [Page 6] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +6. Gatewaying over IP + + In order to facilitate the gradual introduction of BLOAT into the + public Internet, BLOAT MAY be encapsulated in IP as in [RFC2003] to + gateway between networks that run BLOAT natively on their LANs. + +7. DTDs + + The Transport DTDs (7.2. and 7.3.) build on the definitions in the + Network DTD (7.1.) + + The DTDs are referenced by their PubidLiteral and SystemLiteral (from + [XML]) although it is understood that most IPoXML implementations + will not need to pull down the DTD, as it will normally be embedded + in the implementation, and presents something of a catch-22 if you + need to load part of your network protocol over the network. + +7.1. IPoXML DTD + + <!-- + DTD for IP over XML. + Refer to this DTD as: + + <!DOCTYPE ip PUBLIC "-//IETF//DTD BLOAT 1.0 IP//EN" "bloat.dtd"> + --> + <!-- + DTD data types: + + Digits [0..9]+ + + Precedence "NetworkControl | InternetworkControl | + CRITIC | FlashOverride | Flash | Immediate | + Priority | Routine" + + IP4Addr "dotted-decimal" notation of [RFC1123] + + Class [0..3] + + Sec "Unclassified | Confidential | EFTO | MMMM | PROG | + Restricted | Secret | Top Secret | Reserved" + + Compartments [0..65535] + + Handling [0..65535] + + TCC [0..16777216] + + --> + + + +Kennedy Informational [Page 7] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ENTITY % Digits "CDATA"> + <!ENTITY % Precedence "CDATA"> + <!ENTITY % IP4Addr "CDATA"> + <!ENTITY % Class "CDATA"> + <!ENTITY % Sec "CDATA"> + <!ENTITY % Compartments "CDATA"> + <!ENTITY % Handling "CDATA"> + <!ENTITY % TCC "CDATA"> + + <!ELEMENT ip (header, payload)> + + <!ELEMENT header (version, tos, total.length, id, flags, offset, ttl, + protocol, checksum, source, destination, options, + padding)> + <!-- length of header in 32-bit words --> + <!ATTLIST header + length %Digits; #REQUIRED> + + <!ELEMENT version EMPTY> + <!-- ip version. SHOULD be "4" --> + <!ATTLIST version + value %Digits; #REQUIRED> + + <!ELEMENT tos EMPTY> + <!ATTLIST tos + precedence %Precedence; #REQUIRED + delay (normal | low) #REQUIRED + throughput (normal | high) #REQUIRED + relibility (normal | high) #REQUIRED + reserved CDATA #FIXED "0"> + + <!ELEMENT total.length EMPTY> + <!-- + total length of datagram (header and payload) in octets, MUST be + less than 65,535 (and SHOULD be less than 1024 for IPoXML on local + ethernets). + --> + <!ATTLIST total.length + value %Digits; #REQUIRED> + + <!ELEMENT id EMPTY> + <!-- 0 <= id <= 65,535 --> + <!ATTLIST id + value %Digits; #REQUIRED> + + <!ELEMENT flags EMPTY> + <!-- df = don't fragment, mf = more fragments --> + <!ATTLIST flags + + + +Kennedy Informational [Page 8] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + reserved CDATA #FIXED "0" + df (may|dont) #REQUIRED + mf (last|more) #REQUIRED> + + <!ELEMENT offset EMPTY> + <!-- 0 <= offset <= 8192 measured in 8 octet (64-bit) chunks --> + <!ATTLIST offset + value %Digits; #REQUIRED> + + <!ELEMENT ttl EMPTY> + <!-- 0 <= ttl <= 255 --> + <!ATTLIST ttl + value %Digits; #REQUIRED> + + <!ELEMENT protocol EMPTY> + <!-- 0 <= protocol <= 255 (per IANA) --> + <!ATTLIST protocol + value %Digits; #REQUIRED> + + <!ELEMENT checksum EMPTY> + <!-- 0 <= checksum <= 65535 (over header only) --> + <!ATTLIST checksum + value %Digits; #REQUIRED> + + <!ELEMENT source EMPTY> + <!ATTLIST source + address %IP4Addr; #REQUIRED> + + <!ELEMENT destination EMPTY> + <!ATTLIST destination + address %IP4Addr; #REQUIRED> + + <!ELEMENT options ( end | noop | security | loose | strict | record + | stream | timestamp )*> + + <!ELEMENT end EMPTY> + <!ATTLIST end + copied (0|1) #REQUIRED + class CDATA #FIXED "0" + number CDATA #FIXED "0"> + + <!ELEMENT noop EMPTY> + <!ATTLIST noop + copied (0|1) #REQUIRED + class CDATA #FIXED "0" + number CDATA #FIXED "1"> + + <!ELEMENT security EMPTY> + + + +Kennedy Informational [Page 9] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ATTLIST security + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "2" + length CDATA #FIXED "11" + security %Sec; #REQUIRED + compartments %Compartments; #REQUIRED + handling %Handling; #REQUIRED + tcc %TCC; #REQUIRED> + <!ELEMENT loose (hop)+> + <!ATTLIST loose + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "3" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED> + + <!ELEMENT hop EMPTY> + <!ATTLIST hop + address %IP4Addr; #REQUIRED> + + <!ELEMENT strict (hop)+> + <!ATTLIST strict + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "9" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED> + + <!ELEMENT record (hop)+> + <!ATTLIST record + copied CDATA #FIXED "0" + class CDATA #FIXED "0" + number CDATA #FIXED "7" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED> + + <!ELEMENT stream EMPTY> + <!-- 0 <= id <= 65,535 --> + <!ATTLIST stream + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "8" + length CDATA #FIXED "4" + id %Digits; #REQUIRED> + + <!ELEMENT timestamp (tstamp)+> + <!-- 0 <= oflw <=15 --> + + + +Kennedy Informational [Page 10] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ATTLIST timestamp + copied CDATA #FIXED "0" + class CDATA #FIXED "2" + number CDATA #FIXED "4" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED + oflw %Digits; #REQUIRED + flag (0 | 1 | 3) #REQUIRED> + + <!ELEMENT tstamp EMPTY> + <!ATTLIST tstamp + time %Digits; #REQUIRED + address %IP4Addr; #IMPLIED> + <!-- + padding to bring header to 32-bit boundary. + pad MUST be "0"* + --> + <!ELEMENT padding EMPTY> + <!ATTLIST padding + pad CDATA #REQUIRED> + + <!-- payload MUST be encoded as base-64 [RFC2045], as modified + by section 2.1 of this RFC --> + <!ELEMENT payload (CDATA)> + +7.2. TCPoXML DTD + + <!-- + DTD for TCP over XML. + Refer to this DTD as: + + <!DOCTYPE tcp PUBLIC "-//IETF//DTD BLOAT 1.0 TCP//EN" "bloat.dtd"> + --> + + <!-- the pseudoheader is only included for checksum calculations --> + <!ELEMENT tcp (tcp.pseudoheader?, tcp.header, payload)> + + <!ELEMENT tcp.header (src, dest, sequence, acknowledgement, offset, + reserved, control, window, checksum, urgent, + tcp.options, padding)> + + <!ELEMENT src EMPTY> + <!-- 0 <= port <= 65,535 --> + <!ATTLIST src + port %Digits; #REQUIRED> + + <!ELEMENT dest EMPTY> + <!-- 0 <= port <= 65,535 --> + + + +Kennedy Informational [Page 11] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ATTLIST dest + port %Digits; #REQUIRED> + + <!ELEMENT sequence EMPTY> + <!-- 0 <= number <= 4294967295 --> + <!ATTLIST sequence + number %Digits; #REQUIRED> + + <!ELEMENT acknowledgement EMPTY> + <!-- 0 <= number <= 4294967295 --> + <!ATTLIST acknowledgement + number %Digits; #REQUIRED> + + <!ELEMENT offset EMPTY> + <!-- 0 <= number <= 255 --> + <!ATTLIST offset + number %Digits; #REQUIRED> + + <!ELEMENT reserved EMPTY> + <!ATTLIST reserved + value CDATA #FIXED "0"> + + <!ELEMENT control EMPTY> + <!ATTLIST control + urg (0|1) #IMPLIED + ack (0|1) #IMPLIED + psh (0|1) #IMPLIED + rst (0|1) #IMPLIED + syn (0|1) #IMPLIED + fin (0|1) #IMPLIED> + + <!ELEMENT window EMPTY> + <!-- 0 <= size <= 65,535 --> + <!ATTLIST window + size %Digits; #REQUIRED> + + <!-- + checksum as in ip, but with + the following pseudo-header added into the tcp element: + --> + <!ELEMENT tcp.pseudoheader (source, destination, protocol, + tcp.length)> + + <!-- + tcp header + data length in octets. does not include the size of + + the pseudoheader. + --> + + + +Kennedy Informational [Page 12] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ELEMENT tcp.length EMPTY> + <!ATTLIST tcp.length + value %Digits; #REQUIRED> + + <!ELEMENT urgent EMPTY> + <!-- 0 <= pointer <= 65,535 --> + <!ATTLIST urgent + pointer %Digits; #REQUIRED> + + <!ELEMENT tcp.options (tcp.end | tcp.noop | tcp.mss)+> + + <!ELEMENT tcp.end EMPTY> + <!ATTLIST tcp.end + kind CDATA #FIXED "0"> + + <!ELEMENT tcp.noop EMPTY> + <!ATTLIST tcp.noop + kind CDATA #FIXED "1"> + + <!ELEMENT tcp.mss EMPTY> + <!ATTLIST tcp.mss + kind CDATA #FIXED "2" + length CDATA #FIXED "4" + size %Digits; #REQUIRED> + +7.3. UDPoXML DTD + + <!-- + DTD for UDP over XML. + Refer to this DTD as: + + <!DOCTYPE udp PUBLIC "-//IETF//DTD BLOAT 1.0 UDP//EN" "bloat.dtd"> + --> + + <!ELEMENT udp (udp.pseudoheader?, udp.header, payload)> + + <!ELEMENT udp.header (src, dest, udp.length, checksum)> + + <!ELEMENT udp.pseudoheader (source, destination, protocol, + udp.length)> + + <!-- + udp header + data length in octets. does not include the size of + the pseudoheader. + --> + <!ELEMENT udp.length EMPTY> + <!ATTLIST udp.length + value %Digits; #REQUIRED> + + + +Kennedy Informational [Page 13] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +8. Security Considerations + + XML, as a subset of SGML, has the same security considerations as + specified in SGML Media Types [RFC1874]. Security considerations + that apply to IP, TCP and UDP also likely apply to BLOAT as it does + not attempt to correct for issues not related to message format. + +9. References + + [JABBER] Miller, J., "Jabber", draft-miller-jabber-00.txt, + February 2002. (Work in Progress) + + [RFC768] Postel, J., "User Datagram Protocol", STD 6, RFC 768, + August 1980. + + [RFC791] Postel, J., "Internet Protocol", STD 5, RFC 791, + September 1981. + + [RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC + 793, September 1981. + + [RFC894] Hornig, C., "Standard for the Transmission of IP + Datagrams over Ethernet Networks.", RFC 894, April 1984. + + [RFC1042] Postel, J. and J. Reynolds, "Standard for the + Transmission of IP Datagrams Over IEEE 802 Networks", STD + 43, RFC 1042, February 1988. + + [RFC1123] Braden, R., "Requirements for Internet Hosts - + Application and Support", RFC 1123, October 1989. + + [RFC1874] Levinson, E., "SGML Media Types", RFC 1874, December + 1995. + + [RFC2003] Perkins, C., "IP Encapsulation within IP", RFC 2003, + October 1996. + + [RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail + Extensions (MIME) Part One: Format of Internet Message + Bodies", RFC 2045, November 1996. + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO + 10646", RFC 2279, January 1998. + + + + + +Kennedy Informational [Page 14] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6 + (IPv6) Specification", RFC 2460, December 1998. + + [RFC3080] Rose, M., "The Blocks Extensible Exchange Protocol Core", + RFC 3080, March 2001. + + [SOAP] Box, D., Ehnebuske, D., Kakivaya, G., Layman, A., + Mendelsohn, N., Nielsen, H. F., Thatte, S. Winer, D., + "Simple Object Access Protocol (SOAP) 1.1" World Wide Web + Consortium Note, May 2000 http://www.w3.org/TR/SOAP/ + + [XML] Bray, T., Paoli, J., Sperberg-McQueen, C. M., "Extensible + Markup Language (XML)" World Wide Web Consortium + Recommendation REC- xml-19980210. + http://www.w3.org/TR/1998/REC-xml-19980210 + +10. Author's Address + + Hugh Kennedy + Mimezine + 1060 West Addison + Chicago, IL 60613 + USA + + EMail: kennedyh@engin.umich.edu + + + + + + + + + + + + + + + + + + + + + + + + + + +Kennedy Informational [Page 15] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +11. Full Copyright Statement + + Copyright (C) The Internet Society (2002). All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +Acknowledgement + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + + + + + + + + + + + + + + + + +Kennedy Informational [Page 16] + diff --git a/tests/auto/qhttp/trolltech b/tests/auto/qhttp/trolltech new file mode 100644 index 0000000..c155360 --- /dev/null +++ b/tests/auto/qhttp/trolltech @@ -0,0 +1,8 @@ +<html> + <head> + <title>Test</title> + </head> + <body> + <h1>Test</h1> + </body> +</html> diff --git a/tests/auto/qhttp/tst_qhttp.cpp b/tests/auto/qhttp/tst_qhttp.cpp new file mode 100644 index 0000000..e4a798e --- /dev/null +++ b/tests/auto/qhttp/tst_qhttp.cpp @@ -0,0 +1,1530 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> + +#include <qbuffer.h> +#include <qcoreapplication.h> +#include <qfile.h> +#include <qhostinfo.h> +#include <qhttp.h> +#include <qlist.h> +#include <qpointer.h> +#include <qtcpsocket.h> +#include <qtcpserver.h> +#include <qauthenticator.h> +#include <QNetworkProxy> +#ifndef QT_NO_OPENSSL +# include <qsslsocket.h> +#endif + +#include "../network-settings.h" + +//TESTED_CLASS= +//TESTED_FILES= + +Q_DECLARE_METATYPE(QHttpResponseHeader) + +class tst_QHttp : public QObject +{ + Q_OBJECT + +public: + tst_QHttp(); + virtual ~tst_QHttp(); + + +public slots: + void initTestCase_data(); + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); +private slots: + void constructing(); + void invalidRequests(); + void get_data(); + void get(); + void head_data(); + void head(); + void post_data(); + void post(); + void request_data(); + void request(); + void authorization_data(); + void authorization(); + void proxy_data(); + void proxy(); + void proxy2(); + void proxy3(); + void postAuthNtlm(); + void proxyAndSsl(); + void cachingProxyAndSsl(); + void reconnect(); + void setSocket(); + void unexpectedRemoteClose(); + void pctEncodedPath(); + void caseInsensitiveKeys(); + void emptyBodyInReply(); + void abortInReadyRead(); + void abortInResponseHeaderReceived(); + void nestedEventLoop(); + + + // manual tests + void connectionClose(); + +protected slots: + void stateChanged( int ); + void responseHeaderReceived( const QHttpResponseHeader & ); + void readyRead( const QHttpResponseHeader& ); + void dataSendProgress( int, int ); + void dataReadProgress( int , int ); + + void requestStarted( int ); + void requestFinished( int, bool ); + void done( bool ); + + void reconnect_state(int state); + void proxy2_slot(); + void nestedEventLoop_slot(int id); + + void abortSender(); + void proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth); + +private: + QHttp *newHttp(bool withAuth = false); + void addRequest( QHttpRequestHeader, int ); + bool headerAreEqual( const QHttpHeader&, const QHttpHeader& ); + + QHttp *http; + + struct RequestResult + { + QHttpRequestHeader req; + QHttpResponseHeader resp; + int success; + }; + QMap< int, RequestResult > resultMap; + typedef QMap<int,RequestResult>::Iterator ResMapIt; + QList<int> ids; // helper to make sure that all expected signals are emitted + + int current_id; + int cur_state; + int done_success; + + QByteArray readyRead_ba; + + int bytesTotalSend; + int bytesDoneSend; + int bytesTotalRead; + int bytesDoneRead; + + int getId; + int headId; + int postId; + + int reconnect_state_connect_count; + + bool connectionWithAuth; + bool proxyAuthCalled; +}; + +//#define DUMP_SIGNALS + +const int bytesTotal_init = -10; +const int bytesDone_init = -10; + +tst_QHttp::tst_QHttp() +{ +} + +tst_QHttp::~tst_QHttp() +{ +} + +void tst_QHttp::initTestCase_data() +{ + QTest::addColumn<bool>("setProxy"); + QTest::addColumn<int>("proxyType"); + + QTest::newRow("WithoutProxy") << false << 0; + QTest::newRow("WithSocks5Proxy") << true << int(QNetworkProxy::Socks5Proxy); +} + +void tst_QHttp::initTestCase() +{ +} + +void tst_QHttp::cleanupTestCase() +{ +} + +void tst_QHttp::init() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) { + QFETCH_GLOBAL(int, proxyType); + if (proxyType == QNetworkProxy::Socks5Proxy) { + QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::Socks5Proxy, QtNetworkSettings::serverName(), 1080)); + } + } + + http = 0; + + resultMap.clear(); + ids.clear(); + + current_id = 0; + cur_state = QHttp::Unconnected; + done_success = -1; + + readyRead_ba = QByteArray(); + + getId = -1; + headId = -1; + postId = -1; +} + +void tst_QHttp::cleanup() +{ + delete http; + http = 0; + + QCoreApplication::processEvents(); + + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) { + QNetworkProxy::setApplicationProxy(QNetworkProxy::DefaultProxy); + } +} + +void tst_QHttp::constructing() +{ + //QHeader + { + QHttpRequestHeader header; + header.addValue("key1", "val1"); + header.addValue("key2", "val2"); + header.addValue("key1", "val3"); + QCOMPARE(header.values().size(), 3); + QCOMPARE(header.allValues("key1").size(), 2); + QVERIFY(header.hasKey("key2")); + QCOMPARE(header.keys().count(), 2); + + } + +#if QT_VERSION >= 0x040102 + { + QHttpResponseHeader header(200); + } +#endif +} + +void tst_QHttp::invalidRequests() +{ + QHttp http; + http.setHost("localhost"); // we will not actually connect + + QTest::ignoreMessage(QtWarningMsg, "QHttp: empty path requested is invalid -- using '/'"); + http.get(QString()); + + QTest::ignoreMessage(QtWarningMsg, "QHttp: empty path requested is invalid -- using '/'"); + http.head(QString()); + + QTest::ignoreMessage(QtWarningMsg, "QHttp: empty path requested is invalid -- using '/'"); + http.post(QString(), QByteArray()); + + QTest::ignoreMessage(QtWarningMsg, "QHttp: empty path requested is invalid -- using '/'"); + http.request(QHttpRequestHeader("PROPFIND", QString())); +} + +void tst_QHttp::get_data() +{ + QTest::addColumn<QString>("host"); + QTest::addColumn<uint>("port"); + QTest::addColumn<QString>("path"); + QTest::addColumn<int>("success"); + QTest::addColumn<int>("statusCode"); + QTest::addColumn<QByteArray>("res"); + QTest::addColumn<bool>("useIODevice"); + + // ### move this into external testdata + QFile file( SRCDIR "rfc3252.txt" ); + QVERIFY( file.open( QIODevice::ReadOnly ) ); + QByteArray rfc3252 = file.readAll(); + file.close(); + + file.setFileName( SRCDIR "trolltech" ); + QVERIFY( file.open( QIODevice::ReadOnly ) ); + QByteArray trolltech = file.readAll(); + file.close(); + + // test the two get() modes in one routine + for ( int i=0; i<2; i++ ) { + QTest::newRow(QString("path_01_%1").arg(i).toLatin1()) << QtNetworkSettings::serverName() << 80u + << QString("/qtest/rfc3252.txt") << 1 << 200 << rfc3252 << (bool)(i==1); + QTest::newRow( QString("path_02_%1").arg(i).toLatin1() ) << QString("www.ietf.org") << 80u + << QString("/rfc/rfc3252.txt") << 1 << 200 << rfc3252 << (bool)(i==1); + + QTest::newRow( QString("uri_01_%1").arg(i).toLatin1() ) << QtNetworkSettings::serverName() << 80u + << QString("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt") << 1 << 200 << rfc3252 << (bool)(i==1); + QTest::newRow( QString("uri_02_%1").arg(i).toLatin1() ) << "www.ietf.org" << 80u + << QString("http://www.ietf.org/rfc/rfc3252.txt") << 1 << 200 << rfc3252 << (bool)(i==1); + + QTest::newRow( QString("fail_01_%1").arg(i).toLatin1() ) << QString("this-host-will-not-exist.") << 80u + << QString("/qtest/rfc3252.txt") << 0 << 0 << QByteArray() << (bool)(i==1); + + QTest::newRow( QString("failprot_01_%1").arg(i).toLatin1() ) << QtNetworkSettings::serverName() << 80u + << QString("/t") << 1 << 404 << QByteArray() << (bool)(i==1); + QTest::newRow( QString("failprot_02_%1").arg(i).toLatin1() ) << QtNetworkSettings::serverName() << 80u + << QString("qtest/rfc3252.txt") << 1 << 400 << QByteArray() << (bool)(i==1); + + // doc.trolltech.com uses transfer-encoding=chunked + /* doc.trolltech.com no longer seams to be using chuncked encodig. + QTest::newRow( QString("chunked_01_%1").arg(i).toLatin1() ) << QString("test.troll.no") << 80u + << QString("/") << 1 << 200 << trolltech << (bool)(i==1); + */ + QTest::newRow( QString("chunked_02_%1").arg(i).toLatin1() ) << QtNetworkSettings::serverName() << 80u + << QString("/qtest/cgi-bin/rfc.cgi") << 1 << 200 << rfc3252 << (bool)(i==1); + } +} + +void tst_QHttp::get() +{ + // for the overload that takes a QIODevice + QByteArray buf_ba; + QBuffer buf( &buf_ba ); + + QFETCH( QString, host ); + QFETCH( uint, port ); + QFETCH( QString, path ); + QFETCH( bool, useIODevice ); + + http = newHttp(); + QCOMPARE( http->currentId(), 0 ); + QCOMPARE( (int)http->state(), (int)QHttp::Unconnected ); + + addRequest( QHttpRequestHeader(), http->setHost( host, port ) ); + if ( useIODevice ) { + buf.open( QIODevice::WriteOnly ); + getId = http->get( path, &buf ); + } else { + getId = http->get( path ); + } + addRequest( QHttpRequestHeader(), getId ); + + QTestEventLoop::instance().enterLoop( 30 ); + + if ( QTestEventLoop::instance().timeout() ) + QFAIL( "Network operation timed out" ); + + ResMapIt res = resultMap.find( getId ); + QVERIFY( res != resultMap.end() ); + if ( res.value().success!=1 && host=="www.ietf.org" ) { + // The nightly tests fail from time to time. In order to make them more + // stable, add some debug output that might help locate the problem (I + // can't reproduce the problem in the non-nightly builds). + qDebug( "Error %d: %s", http->error(), http->errorString().toLatin1().constData() ); + } + QTEST( res.value().success, "success" ); + if ( res.value().success ) { + QTEST( res.value().resp.statusCode(), "statusCode" ); + + QFETCH( QByteArray, res ); + if ( res.count() > 0 ) { + if ( useIODevice ) { + QCOMPARE(buf_ba, res); + if ( bytesDoneRead != bytesDone_init ) + QVERIFY( (int)buf_ba.size() == bytesDoneRead ); + } else { + QCOMPARE(readyRead_ba, res); + if ( bytesDoneRead != bytesDone_init ) + QVERIFY( (int)readyRead_ba.size() == bytesDoneRead ); + } + } + QVERIFY( bytesTotalRead != bytesTotal_init ); + if ( bytesTotalRead > 0 ) + QVERIFY( bytesDoneRead == bytesTotalRead ); + } else { + QVERIFY( !res.value().resp.isValid() ); + } +} + +void tst_QHttp::head_data() +{ + QTest::addColumn<QString>("host"); + QTest::addColumn<uint>("port"); + QTest::addColumn<QString>("path"); + QTest::addColumn<int>("success"); + QTest::addColumn<int>("statusCode"); + QTest::addColumn<uint>("contentLength"); + + QTest::newRow( "path_01" ) << QtNetworkSettings::serverName() << 80u + << QString("/qtest/rfc3252.txt") << 1 << 200 << 25962u; + QTest::newRow( "path_02" ) << QString("www.ietf.org") << 80u + << QString("/rfc/rfc3252.txt") << 1 << 200 << 25962u; + + QTest::newRow( "uri_01" ) << QtNetworkSettings::serverName() << 80u + << QString("http://" + QtNetworkSettings::serverName() + "/qtest/rfc3252.txt") << 1 << 200 << 25962u; + QTest::newRow( "uri_02" ) << QString("www.ietf.org") << 80u + << QString("http://www.ietf.org/rfc/rfc3252.txt") << 1 << 200 << 25962u; + + QTest::newRow( "fail_01" ) << QString("this-host-will-not-exist.") << 80u + << QString("/qtest/rfc3252.txt") << 0 << 0 << 0u; + + QTest::newRow( "failprot_01" ) << QtNetworkSettings::serverName() << 80u + << QString("/t") << 1 << 404 << 0u; + QTest::newRow( "failprot_02" ) << QtNetworkSettings::serverName() << 80u + << QString("qtest/rfc3252.txt") << 1 << 400 << 0u; + + /* doc.trolltech.com no longer seams to be using chuncked encodig. + QTest::newRow( "chunked_01" ) << QString("doc.trolltech.com") << 80u + << QString("/index.html") << 1 << 200 << 0u; + */ + QTest::newRow( "chunked_02" ) << QtNetworkSettings::serverName() << 80u + << QString("/qtest/cgi-bin/rfc.cgi") << 1 << 200 << 0u; +} + +void tst_QHttp::head() +{ + QFETCH( QString, host ); + QFETCH( uint, port ); + QFETCH( QString, path ); + + http = newHttp(); + QCOMPARE( http->currentId(), 0 ); + QCOMPARE( (int)http->state(), (int)QHttp::Unconnected ); + + addRequest( QHttpRequestHeader(), http->setHost( host, port ) ); + headId = http->head( path ); + addRequest( QHttpRequestHeader(), headId ); + + QTestEventLoop::instance().enterLoop( 30 ); + if ( QTestEventLoop::instance().timeout() ) + QFAIL( "Network operation timed out" ); + + ResMapIt res = resultMap.find( headId ); + QVERIFY( res != resultMap.end() ); + if ( res.value().success!=1 && host=="www.ietf.org" ) { + // The nightly tests fail from time to time. In order to make them more + // stable, add some debug output that might help locate the problem (I + // can't reproduce the problem in the non-nightly builds). + qDebug( "Error %d: %s", http->error(), http->errorString().toLatin1().constData() ); + } + QTEST( res.value().success, "success" ); + if ( res.value().success ) { + QTEST( res.value().resp.statusCode(), "statusCode" ); + QTEST( res.value().resp.contentLength(), "contentLength" ); + + QCOMPARE( (uint)readyRead_ba.size(), 0u ); + QVERIFY( bytesTotalRead == bytesTotal_init ); + QVERIFY( bytesDoneRead == bytesDone_init ); + } else { + QVERIFY( !res.value().resp.isValid() ); + } +} + +void tst_QHttp::post_data() +{ + QTest::addColumn<QString>("source"); + QTest::addColumn<bool>("useIODevice"); + QTest::addColumn<bool>("useProxy"); + QTest::addColumn<QString>("host"); + QTest::addColumn<int>("port"); + QTest::addColumn<QString>("path"); + QTest::addColumn<QByteArray>("result"); + + QByteArray md5sum; + md5sum = "d41d8cd98f00b204e9800998ecf8427e"; + QTest::newRow("empty-data") + << QString() << false << false + << QtNetworkSettings::serverName() << 80 << "/qtest/cgi-bin/md5sum.cgi" << md5sum; + QTest::newRow("empty-device") + << QString() << true << false + << QtNetworkSettings::serverName() << 80 << "/qtest/cgi-bin/md5sum.cgi" << md5sum; + QTest::newRow("proxy-empty-data") + << QString() << false << true + << QtNetworkSettings::serverName() << 80 << "/qtest/cgi-bin/md5sum.cgi" << md5sum; + + md5sum = "b3e32ac459b99d3f59318f3ac31e4bee"; + QTest::newRow("data") << "rfc3252.txt" << false << false + << QtNetworkSettings::serverName() << 80 << "/qtest/cgi-bin/md5sum.cgi" + << md5sum; + QTest::newRow("device") << "rfc3252.txt" << true << false + << QtNetworkSettings::serverName() << 80 << "/qtest/cgi-bin/md5sum.cgi" + << md5sum; + QTest::newRow("proxy-data") << "rfc3252.txt" << false << true + << QtNetworkSettings::serverName() << 80 << "/qtest/cgi-bin/md5sum.cgi" + << md5sum; + + // the following test won't work. See task 185996 +/* + QTest::newRow("proxy-device") << "rfc3252.txt" << true << true + << QtNetworkSettings::serverName() << 80 << "/qtest/cgi-bin/md5sum.cgi" + << md5sum; +*/ +} + +void tst_QHttp::post() +{ + QFETCH(QString, source); + QFETCH(bool, useIODevice); + QFETCH(bool, useProxy); + QFETCH(QString, host); + QFETCH(int, port); + QFETCH(QString, path); + + http = newHttp(useProxy); + QCOMPARE(http->currentId(), 0); + QCOMPARE((int)http->state(), (int)QHttp::Unconnected); + if (useProxy) + addRequest(QHttpRequestHeader(), http->setProxy(QtNetworkSettings::serverName(), 3129)); + addRequest(QHttpRequestHeader(), http->setHost(host, port)); + + // add the POST request + QFile file(SRCDIR + source); + QBuffer emptyBuffer; + QIODevice *dev; + if (!source.isEmpty()) { + QVERIFY(file.open(QIODevice::ReadOnly)); + dev = &file; + } else { + emptyBuffer.open(QIODevice::ReadOnly); + dev = &emptyBuffer; + } + + if (useIODevice) + postId = http->post(path, dev); + else + postId = http->post(path, dev->readAll()); + addRequest(QHttpRequestHeader(), postId); + + // run request + connect(http, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); + QTestEventLoop::instance().enterLoop( 30 ); + + if ( QTestEventLoop::instance().timeout() ) + QFAIL( "Network operation timed out" ); + + ResMapIt res = resultMap.find(postId); + QVERIFY(res != resultMap.end()); + QVERIFY(res.value().success); + QCOMPARE(res.value().resp.statusCode(), 200); + QTEST(readyRead_ba.trimmed(), "result"); +} + +void tst_QHttp::request_data() +{ + QTest::addColumn<QString>("source"); + QTest::addColumn<bool>("useIODevice"); + QTest::addColumn<bool>("useProxy"); + QTest::addColumn<QString>("host"); + QTest::addColumn<int>("port"); + QTest::addColumn<QString>("method"); + QTest::addColumn<QString>("path"); + QTest::addColumn<QByteArray>("result"); + + QFile source(SRCDIR "rfc3252.txt"); + if (!source.open(QIODevice::ReadOnly)) + return; + + QByteArray contents = source.readAll(); + QByteArray md5sum = QCryptographicHash::hash(contents, QCryptographicHash::Md5).toHex() + '\n'; + QByteArray emptyMd5sum = "d41d8cd98f00b204e9800998ecf8427e\n"; + + QTest::newRow("head") << QString() << false << false << QtNetworkSettings::serverName() << 80 + << "HEAD" << "/qtest/rfc3252.txt" + << QByteArray(); + QTest::newRow("get") << QString() << false << false << QtNetworkSettings::serverName() << 80 + << "GET" << "/qtest/rfc3252.txt" + << contents; + QTest::newRow("post-empty-data") << QString() << false << false + << QtNetworkSettings::serverName() << 80 << "POST" << "/qtest/cgi-bin/md5sum.cgi" + << emptyMd5sum; + QTest::newRow("post-empty-device") << QString() << true << false + << QtNetworkSettings::serverName() << 80 << "POST" << "/qtest/cgi-bin/md5sum.cgi" + << emptyMd5sum; + QTest::newRow("post-data") << "rfc3252.txt" << false << false + << QtNetworkSettings::serverName() << 80 << "POST" << "/qtest/cgi-bin/md5sum.cgi" + << md5sum; + QTest::newRow("post-device") << "rfc3252.txt" << true << false + << QtNetworkSettings::serverName() << 80 << "POST" << "/qtest/cgi-bin/md5sum.cgi" + << md5sum; + + QTest::newRow("proxy-head") << QString() << false << true << QtNetworkSettings::serverName() << 80 + << "HEAD" << "/qtest/rfc3252.txt" + << QByteArray(); + QTest::newRow("proxy-get") << QString() << false << true << QtNetworkSettings::serverName() << 80 + << "GET" << "/qtest/rfc3252.txt" + << contents; + QTest::newRow("proxy-post-empty-data") << QString() << false << true + << QtNetworkSettings::serverName() << 80 << "POST" << "/qtest/cgi-bin/md5sum.cgi" + << emptyMd5sum; + QTest::newRow("proxy-post-data") << "rfc3252.txt" << false << true + << QtNetworkSettings::serverName() << 80 << "POST" << "/qtest/cgi-bin/md5sum.cgi" + << md5sum; + + // the following test won't work. See task 185996 +/* + QTest::newRow("proxy-post-device") << "rfc3252.txt" << true << true + << QtNetworkSettings::serverName() << 80 << "POST" << "/qtest/cgi-bin/md5sum.cgi" + << md5sum; +*/ +} + +void tst_QHttp::request() +{ + QFETCH(QString, source); + QFETCH(bool, useIODevice); + QFETCH(bool, useProxy); + QFETCH(QString, host); + QFETCH(int, port); + QFETCH(QString, method); + QFETCH(QString, path); + + http = newHttp(useProxy); + QCOMPARE(http->currentId(), 0); + QCOMPARE((int)http->state(), (int)QHttp::Unconnected); + if (useProxy) + addRequest(QHttpRequestHeader(), http->setProxy(QtNetworkSettings::serverName(), 3129)); + addRequest(QHttpRequestHeader(), http->setHost(host, port)); + + QFile file(SRCDIR + source); + QBuffer emptyBuffer; + QIODevice *dev; + if (!source.isEmpty()) { + QVERIFY(file.open(QIODevice::ReadOnly)); + dev = &file; + } else { + emptyBuffer.open(QIODevice::ReadOnly); + dev = &emptyBuffer; + } + + // prepare the request + QHttpRequestHeader request; + request.setRequest(method, path, 1,1); + request.addValue("Host", host); + int *theId; + + if (method == "POST") + theId = &postId; + else if (method == "GET") + theId = &getId; + else if (method == "HEAD") + theId = &headId; + else + QFAIL("You're lazy! Please implement your test!"); + + // now send the request + if (useIODevice) + *theId = http->request(request, dev); + else + *theId = http->request(request, dev->readAll()); + addRequest(QHttpRequestHeader(), *theId); + + // run request + connect(http, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); + QTestEventLoop::instance().enterLoop( 30 ); + + if ( QTestEventLoop::instance().timeout() ) + QFAIL( "Network operation timed out" ); + + ResMapIt res = resultMap.find(*theId); + QVERIFY(res != resultMap.end()); + QVERIFY(res.value().success); + QCOMPARE(res.value().resp.statusCode(), 200); + QTEST(readyRead_ba, "result"); +} + +void tst_QHttp::authorization_data() +{ + QTest::addColumn<QString>("host"); + QTest::addColumn<QString>("path"); + QTest::addColumn<QString>("user"); + QTest::addColumn<QString>("pass"); + QTest::addColumn<int>("result"); + + QTest::newRow("correct password") << QtNetworkSettings::serverName() + << QString::fromLatin1("/qtest/rfcs-auth/index.html") + << QString::fromLatin1("httptest") + << QString::fromLatin1("httptest") + << 200; + + QTest::newRow("no password") << QtNetworkSettings::serverName() + << QString::fromLatin1("/qtest/rfcs-auth/index.html") + << QString::fromLatin1("") + << QString::fromLatin1("") + << 401; + + QTest::newRow("wrong password") << QtNetworkSettings::serverName() + << QString::fromLatin1("/qtest/rfcs-auth/index.html") + << QString::fromLatin1("maliciu0s") + << QString::fromLatin1("h4X0r") + << 401; +} + +void tst_QHttp::authorization() +{ + QFETCH(QString, host); + QFETCH(QString, path); + QFETCH(QString, user); + QFETCH(QString, pass); + QFETCH(int, result); + + QEventLoop loop; + + QHttp http; + connect(&http, SIGNAL(done(bool)), &loop, SLOT(quit())); + + if (!user.isEmpty()) + http.setUser(user, pass); + http.setHost(host); + int id = http.get(path); + + QTimer::singleShot(5000, &loop, SLOT(quit())); + loop.exec(); + + QCOMPARE(http.lastResponse().statusCode(), result); +} + +void tst_QHttp::proxy_data() +{ + QTest::addColumn<QString>("proxyhost"); + QTest::addColumn<int>("port"); + QTest::addColumn<QString>("host"); + QTest::addColumn<QString>("path"); + QTest::addColumn<QString>("proxyuser"); + QTest::addColumn<QString>("proxypass"); + + QTest::newRow("qt-test-server") << QtNetworkSettings::serverName() << 3128 + << QString::fromLatin1("www.qtsoftware.com") << QString::fromLatin1("/") + << QString::fromLatin1("") << QString::fromLatin1(""); + QTest::newRow("qt-test-server pct") << QtNetworkSettings::serverName() << 3128 + << QString::fromLatin1("www.qtsoftware.com") << QString::fromLatin1("/%64eveloper") + << QString::fromLatin1("") << QString::fromLatin1(""); + QTest::newRow("qt-test-server-basic") << QtNetworkSettings::serverName() << 3129 + << QString::fromLatin1("www.qtsoftware.com") << QString::fromLatin1("/") + << QString::fromLatin1("qsockstest") << QString::fromLatin1("password"); + +#if 0 + // NTLM requires sending the same request three times for it to work + // the tst_QHttp class is too strict to handle the byte counts sent by dataSendProgress + // So don't run this test: + QTest::newRow("qt-test-server-ntlm") << QtNetworkSettings::serverName() << 3130 + << QString::fromLatin1("www.qtsoftware.com") << QString::fromLatin1("/") + << QString::fromLatin1("qsockstest") << QString::fromLatin1("password"); +#endif +} + +void tst_QHttp::proxy() +{ + QFETCH(QString, proxyhost); + QFETCH(int, port); + QFETCH(QString, host); + QFETCH(QString, path); + QFETCH(QString, proxyuser); + QFETCH(QString, proxypass); + + http = newHttp(!proxyuser.isEmpty()); + + QCOMPARE(http->currentId(), 0); + QCOMPARE((int)http->state(), (int)QHttp::Unconnected); + + addRequest(QHttpRequestHeader(), http->setProxy(proxyhost, port, proxyuser, proxypass)); + addRequest(QHttpRequestHeader(), http->setHost(host)); + getId = http->get(path); + addRequest(QHttpRequestHeader(), getId); + + QTestEventLoop::instance().enterLoop(30); + if (QTestEventLoop::instance().timeout()) + QFAIL("Network operation timed out"); + + ResMapIt res = resultMap.find(getId); + QVERIFY(res != resultMap.end()); + QVERIFY(res.value().success); + QCOMPARE(res.value().resp.statusCode(), 200); +} + +void tst_QHttp::proxy2() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + readyRead_ba.clear(); + + QHttp http; + http.setProxy(QtNetworkSettings::serverName(), 3128); + http.setHost(QtNetworkSettings::serverName()); + http.get("/index.html"); + http.get("/index.html"); + + connect(&http, SIGNAL(requestFinished(int, bool)), + this, SLOT(proxy2_slot())); + QTestEventLoop::instance().enterLoop(30); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(readyRead_ba.count("Welcome to fluke.troll.no"), 2); + + readyRead_ba.clear(); +} + +void tst_QHttp::proxy2_slot() +{ + QHttp *http = static_cast<QHttp *>(sender()); + readyRead_ba.append(http->readAll()); + if (!http->hasPendingRequests()) + QTestEventLoop::instance().exitLoop(); +} + +void tst_QHttp::proxy3() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + readyRead_ba.clear(); + + QTcpSocket socket; + socket.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3128)); + + QHttp http; + http.setSocket(&socket); + http.setHost(QtNetworkSettings::serverName()); + http.get("/index.html"); + http.get("/index.html"); + + connect(&http, SIGNAL(requestFinished(int, bool)), + this, SLOT(proxy2_slot())); + QTestEventLoop::instance().enterLoop(30); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(readyRead_ba.count("Welcome to fluke.troll.no"), 2); + + readyRead_ba.clear(); +} + +// test QHttp::currentId() and QHttp::currentRequest() +#define CURRENTREQUEST_TEST \ + { \ + ResMapIt res = resultMap.find( http->currentId() ); \ + QVERIFY( res != resultMap.end() ); \ + if ( http->currentId() == getId ) { \ + QCOMPARE( http->currentRequest().method(), QString("GET") ); \ + } else if ( http->currentId() == headId ) { \ + QCOMPARE( http->currentRequest().method(), QString("HEAD") ); \ + } else if ( http->currentId() == postId ) { \ + QCOMPARE( http->currentRequest().method(), QString("POST") ); \ + } else { \ + QVERIFY( headerAreEqual( http->currentRequest(), res.value().req ) ); \ + } \ + } + +void tst_QHttp::requestStarted( int id ) +{ +#if defined( DUMP_SIGNALS ) + qDebug( "%d:requestStarted( %d )", http->currentId(), id ); +#endif + // make sure that the requestStarted and requestFinished are nested correctly + QVERIFY( current_id == 0 ); + current_id = id; + + QVERIFY( !ids.isEmpty() ); + QVERIFY( ids.first() == id ); + if ( ids.count() > 1 ) { + QVERIFY( http->hasPendingRequests() ); + } else { + QVERIFY( !http->hasPendingRequests() ); + } + + QVERIFY( http->currentId() == id ); + QVERIFY( cur_state == http->state() ); + + + + + CURRENTREQUEST_TEST; + + QVERIFY( http->error() == QHttp::NoError ); +} + +void tst_QHttp::requestFinished( int id, bool error ) +{ +#if defined( DUMP_SIGNALS ) + qDebug( "%d:requestFinished( %d, %d ) -- errorString: '%s'", + http->currentId(), id, (int)error, http->errorString().latin1() ); +#endif + // make sure that the requestStarted and requestFinished are nested correctly + QVERIFY( current_id == id ); + current_id = 0; + + QVERIFY( !ids.isEmpty() ); + QVERIFY( ids.first() == id ); + if ( ids.count() > 1 ) { + QVERIFY( http->hasPendingRequests() ); + } else { + QVERIFY( !http->hasPendingRequests() ); + } + + if ( error ) { + QVERIFY( http->error() != QHttp::NoError ); + ids.clear(); + } else { + QVERIFY( http->error() == QHttp::NoError ); + ids.pop_front(); + } + + QVERIFY( http->currentId() == id ); + QVERIFY( cur_state == http->state() ); + CURRENTREQUEST_TEST; + + ResMapIt res = resultMap.find( http->currentId() ); + QVERIFY( res != resultMap.end() ); + QVERIFY( res.value().success == -1 ); + if ( error ) + res.value().success = 0; + else + res.value().success = 1; +} + +void tst_QHttp::done( bool error ) +{ +#if defined( DUMP_SIGNALS ) + qDebug( "%d:done( %d )", http->currentId(), (int)error ); +#endif + QVERIFY( http->currentId() == 0 ); + QVERIFY( current_id == 0 ); + QVERIFY( ids.isEmpty() ); + QVERIFY( cur_state == http->state() ); + QVERIFY( !http->hasPendingRequests() ); + + QVERIFY( done_success == -1 ); + if ( error ) { + QVERIFY( http->error() != QHttp::NoError ); + done_success = 0; + } else { + QVERIFY( http->error() == QHttp::NoError ); + done_success = 1; + } + QTestEventLoop::instance().exitLoop(); +} + +void tst_QHttp::stateChanged( int state ) +{ +#if defined( DUMP_SIGNALS ) + qDebug( "%d: stateChanged( %d )", http->currentId(), state ); +#endif + QCOMPARE( http->currentId(), current_id ); + if ( ids.count() > 0 ) + CURRENTREQUEST_TEST; + + QVERIFY( state != cur_state ); + QVERIFY( state == http->state() ); + if ( state != QHttp::Unconnected && !connectionWithAuth ) { + // make sure that the states are always emitted in the right order (for + // this, we assume an ordering on the enum values, which they have at + // the moment) + // connections with authentication will possibly reconnect, so ignore them + QVERIFY( cur_state < state ); + } + cur_state = state; + + if (state == QHttp::Connecting) { + bytesTotalSend = bytesTotal_init; + bytesDoneSend = bytesDone_init; + bytesTotalRead = bytesTotal_init; + bytesDoneRead = bytesDone_init; + } +} + +void tst_QHttp::responseHeaderReceived( const QHttpResponseHeader &header ) +{ +#if defined( DUMP_SIGNALS ) + qDebug( "%d: responseHeaderReceived(\n---{\n%s}---)", http->currentId(), header.toString().latin1() ); +#endif + QCOMPARE( http->currentId(), current_id ); + if ( ids.count() > 1 ) { + QVERIFY( http->hasPendingRequests() ); + } else { + QVERIFY( !http->hasPendingRequests() ); + } + CURRENTREQUEST_TEST; + + resultMap[ http->currentId() ].resp = header; +} + +void tst_QHttp::readyRead( const QHttpResponseHeader & ) +{ +#if defined( DUMP_SIGNALS ) + qDebug( "%d: readyRead()", http->currentId() ); +#endif + QCOMPARE( http->currentId(), current_id ); + if ( ids.count() > 1 ) { + QVERIFY( http->hasPendingRequests() ); + } else { + QVERIFY( !http->hasPendingRequests() ); + } + QVERIFY( cur_state == http->state() ); + CURRENTREQUEST_TEST; + + if ( QTest::currentTestFunction() != QLatin1String("bytesAvailable") ) { + int oldSize = readyRead_ba.size(); + quint64 bytesAvail = http->bytesAvailable(); + QByteArray ba = http->readAll(); + QVERIFY( (quint64) ba.size() == bytesAvail ); + readyRead_ba.resize( oldSize + ba.size() ); + memcpy( readyRead_ba.data()+oldSize, ba.data(), ba.size() ); + + if ( bytesTotalRead > 0 ) { + QVERIFY( (int)readyRead_ba.size() <= bytesTotalRead ); + } + QVERIFY( (int)readyRead_ba.size() == bytesDoneRead ); + } +} + +void tst_QHttp::dataSendProgress( int done, int total ) +{ +#if defined( DUMP_SIGNALS ) + qDebug( "%d: dataSendProgress( %d, %d )", http->currentId(), done, total ); +#endif + QCOMPARE( http->currentId(), current_id ); + if ( ids.count() > 1 ) { + QVERIFY( http->hasPendingRequests() ); + } else { + QVERIFY( !http->hasPendingRequests() ); + } + QVERIFY( cur_state == http->state() ); + CURRENTREQUEST_TEST; + + if ( bytesTotalSend == bytesTotal_init ) { + bytesTotalSend = total; + } else { + QCOMPARE( bytesTotalSend, total ); + } + + QVERIFY( bytesTotalSend != bytesTotal_init ); + QVERIFY( bytesDoneSend <= done ); + bytesDoneSend = done; + if ( bytesTotalSend > 0 ) { + QVERIFY( bytesDoneSend <= bytesTotalSend ); + } + + if ( QTest::currentTestFunction() == QLatin1String("abort") ) { + // ### it would be nice if we could specify in our testdata when to do + // the abort + if ( done >= total/100000 ) { + if ( ids.count() != 1 ) { + // do abort only once + int tmpId = ids.first(); + ids.clear(); + ids << tmpId; + http->abort(); + } + } + } +} + +void tst_QHttp::dataReadProgress( int done, int total ) +{ +#if defined( DUMP_SIGNALS ) + qDebug( "%d: dataReadProgress( %d, %d )", http->currentId(), done, total ); +#endif + QCOMPARE( http->currentId(), current_id ); + if ( ids.count() > 1 ) { + QVERIFY( http->hasPendingRequests() ); + } else { + QVERIFY( !http->hasPendingRequests() ); + } + QVERIFY( cur_state == http->state() ); + CURRENTREQUEST_TEST; + + if ( bytesTotalRead == bytesTotal_init ) + bytesTotalRead = total; + else { + QVERIFY( bytesTotalRead == total ); + } + + QVERIFY( bytesTotalRead != bytesTotal_init ); + QVERIFY( bytesDoneRead <= done ); + bytesDoneRead = done; + if ( bytesTotalRead > 0 ) { + QVERIFY( bytesDoneRead <= bytesTotalRead ); + } + + if ( QTest::currentTestFunction() == QLatin1String("abort") ) { + // ### it would be nice if we could specify in our testdata when to do + // the abort + if ( done >= total/100000 ) { + if ( ids.count() != 1 ) { + // do abort only once + int tmpId = ids.first(); + ids.clear(); + ids << tmpId; + http->abort(); + } + } + } +} + + +QHttp *tst_QHttp::newHttp(bool withAuth) +{ + QHttp *nHttp = new QHttp( 0 ); + connect( nHttp, SIGNAL(requestStarted(int)), + SLOT(requestStarted(int)) ); + connect( nHttp, SIGNAL(requestFinished(int,bool)), + SLOT(requestFinished(int,bool)) ); + connect( nHttp, SIGNAL(done(bool)), + SLOT(done(bool)) ); + connect( nHttp, SIGNAL(stateChanged(int)), + SLOT(stateChanged(int)) ); + connect( nHttp, SIGNAL(responseHeaderReceived(const QHttpResponseHeader&)), + SLOT(responseHeaderReceived(const QHttpResponseHeader&)) ); + connect( nHttp, SIGNAL(readyRead(const QHttpResponseHeader&)), + SLOT(readyRead(const QHttpResponseHeader&)) ); + connect( nHttp, SIGNAL(dataSendProgress(int,int)), + SLOT(dataSendProgress(int,int)) ); + connect( nHttp, SIGNAL(dataReadProgress(int,int)), + SLOT(dataReadProgress(int,int)) ); + + connectionWithAuth = withAuth; + return nHttp; +} + +void tst_QHttp::addRequest( QHttpRequestHeader header, int id ) +{ + ids << id; + RequestResult res; + res.req = header; + res.success = -1; + resultMap[ id ] = res; +} + +bool tst_QHttp::headerAreEqual( const QHttpHeader &h1, const QHttpHeader &h2 ) +{ + if ( !h1.isValid() ) + return !h2.isValid(); + if ( !h2.isValid() ) + return !h1.isValid(); + + return h1.toString() == h2.toString(); +} + + +void tst_QHttp::reconnect() +{ + reconnect_state_connect_count = 0; + + QHttp http; + + QObject::connect(&http, SIGNAL(stateChanged(int)), this, SLOT(reconnect_state(int))); + http.setHost("trolltech.com", 80); + http.get("/company/index.html"); + http.setHost("trolltech.com", 8080); + http.get("/company/index.html"); + + QTestEventLoop::instance().enterLoop(60); + if (QTestEventLoop::instance().timeout()) + QFAIL("Network operation timed out"); + + QCOMPARE(reconnect_state_connect_count, 1); + + QTestEventLoop::instance().enterLoop(60); + if (QTestEventLoop::instance().timeout()) + QFAIL("Network operation timed out"); + + QCOMPARE(reconnect_state_connect_count, 2); +} + +void tst_QHttp::reconnect_state(int state) +{ + if (state == QHttp::Connecting) { + ++reconnect_state_connect_count; + QTestEventLoop::instance().exitLoop(); + } +} + +void tst_QHttp::setSocket() +{ + QHttp *http = new QHttp; + QPointer<QTcpSocket> replacementSocket = new QTcpSocket; + http->setSocket(replacementSocket); + QCoreApplication::processEvents(); + delete http; + QVERIFY(replacementSocket); + delete replacementSocket; +} + +class Server : public QTcpServer +{ + Q_OBJECT +public: + Server() + { + connect(this, SIGNAL(newConnection()), + this, SLOT(serveConnection())); + } + +private slots: + void serveConnection() + { + QTcpSocket *socket = nextPendingConnection(); + socket->write("HTTP/1.1 404 Not found\r\n" + "content-length: 4\r\n\r\nabcd"); + socket->disconnectFromHost(); + } +}; + +void tst_QHttp::unexpectedRemoteClose() +{ + QFETCH_GLOBAL(int, proxyType); + if (proxyType == QNetworkProxy::Socks5Proxy) { + // This test doesn't make sense for SOCKS5 + return; + } + + Server server; + server.listen(); + QCoreApplication::instance()->processEvents(); + + QEventLoop loop; + QTimer::singleShot(3000, &loop, SLOT(quit())); + + QHttp http; + QObject::connect(&http, SIGNAL(done(bool)), &loop, SLOT(quit())); + QSignalSpy finishedSpy(&http, SIGNAL(requestFinished(int, bool))); + QSignalSpy doneSpy(&http, SIGNAL(done(bool))); + + http.setHost("localhost", server.serverPort()); + http.get("/"); + http.get("/"); + http.get("/"); + + loop.exec(); + + QCOMPARE(finishedSpy.count(), 4); + QVERIFY(!finishedSpy.at(1).at(1).toBool()); + QVERIFY(!finishedSpy.at(2).at(1).toBool()); + QVERIFY(!finishedSpy.at(3).at(1).toBool()); + QCOMPARE(doneSpy.count(), 1); + QVERIFY(!doneSpy.at(0).at(0).toBool()); +} + +void tst_QHttp::pctEncodedPath() +{ + QHttpRequestHeader header; + header.setRequest("GET", "/index.asp/a=%20&b=%20&c=%20"); + QCOMPARE(header.toString(), QString("GET /index.asp/a=%20&b=%20&c=%20 HTTP/1.1\r\n\r\n")); +} + +void tst_QHttp::caseInsensitiveKeys() +{ + QHttpResponseHeader header("HTTP/1.1 200 OK\r\nContent-Length: 213\r\nX-Been-There: True\r\nLocation: http://www.TrollTech.com/\r\n\r\n"); + QVERIFY(header.hasKey("Content-Length")); + QVERIFY(header.hasKey("X-Been-There")); + QVERIFY(header.hasKey("Location")); + QVERIFY(header.hasKey("content-length")); + QVERIFY(header.hasKey("x-been-there")); + QVERIFY(header.hasKey("location")); + QCOMPARE(header.value("Content-Length"), QString("213")); + QCOMPARE(header.value("X-Been-There"), QString("True")); + QCOMPARE(header.value("Location"), QString("http://www.TrollTech.com/")); + QCOMPARE(header.value("content-length"), QString("213")); + QCOMPARE(header.value("x-been-there"), QString("True")); + QCOMPARE(header.value("location"), QString("http://www.TrollTech.com/")); + QCOMPARE(header.allValues("location"), QStringList("http://www.TrollTech.com/")); + + header.addValue("Content-Length", "213"); + header.addValue("Content-Length", "214"); + header.addValue("Content-Length", "215"); + qDebug() << header.toString(); +} + +void tst_QHttp::proxyAuthenticationRequired(const QNetworkProxy &, QAuthenticator *auth) +{ + proxyAuthCalled = true; + auth->setUser("qsockstest"); + auth->setPassword("password"); +} + +void tst_QHttp::postAuthNtlm() +{ + QSKIP("NTLM not working", SkipAll); + + QHostInfo info = QHostInfo::fromName(QHostInfo::localHostName()); + QByteArray postData("Hello World"); + QHttp http; + + http.setHost(QtNetworkSettings::serverName()); + http.setProxy(QtNetworkSettings::serverName(), 3130); + http.post("/", postData); + + proxyAuthCalled = false; + connect(&http, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); + + QObject::connect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(3); + QObject::disconnect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + + QVERIFY(proxyAuthCalled); + QVERIFY(!QTestEventLoop::instance().timeout()); +}; + +void tst_QHttp::proxyAndSsl() +{ +#ifdef QT_NO_OPENSSL + QSKIP("No OpenSSL support in this platform", SkipAll); +#else + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + QHttp http; + + http.setHost(QtNetworkSettings::serverName(), QHttp::ConnectionModeHttps); + http.setProxy(QNetworkProxy(QNetworkProxy::HttpProxy, QtNetworkSettings::serverName(), 3129)); + http.get("/"); + + proxyAuthCalled = false; + connect(&http, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); + connect(&http, SIGNAL(sslErrors(QList<QSslError>)), + &http, SLOT(ignoreSslErrors())); + + QObject::connect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(3); + QObject::disconnect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + + QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(proxyAuthCalled); + + QHttpResponseHeader header = http.lastResponse(); + QVERIFY(header.isValid()); + QVERIFY(header.statusCode() < 400); // Should be 200, but as long as it's not an error, we're happy +#endif +} + +void tst_QHttp::cachingProxyAndSsl() +{ +#ifdef QT_NO_OPENSSL + QSKIP("No OpenSSL support in this platform", SkipAll); +#else + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + QHttp http; + + http.setHost(QtNetworkSettings::serverName(), QHttp::ConnectionModeHttps); + http.setProxy(QNetworkProxy(QNetworkProxy::HttpCachingProxy, QtNetworkSettings::serverName(), 3129)); + http.get("/"); + + proxyAuthCalled = false; + connect(&http, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); + + QObject::connect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(3); + QObject::disconnect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + + QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(!proxyAuthCalled); // NOT called! QHttp should get a socket error + QVERIFY(http.state() != QHttp::Connected); + + QHttpResponseHeader header = http.lastResponse(); + QVERIFY(!header.isValid()); +#endif +} + +void tst_QHttp::emptyBodyInReply() +{ + // Note: if this test starts failing, please verify the date on the file + // returned by Apache on http://fluke.troll.no/ + // It is right now hard-coded to the date below + QHttp http; + http.setHost(QtNetworkSettings::serverName()); + + QHttpRequestHeader headers("GET", "/"); + headers.addValue("If-Modified-Since", "Sun, 16 Nov 2008 12:29:51 GMT"); + headers.addValue("Host", QtNetworkSettings::serverName()); + http.request(headers); + + QObject::connect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QObject::disconnect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + + QVERIFY(!QTestEventLoop::instance().timeout()); + + // check the reply + if (http.lastResponse().statusCode() != 304) { + qWarning() << http.lastResponse().statusCode() << qPrintable(http.lastResponse().reasonPhrase()); + qWarning() << "Last-Modified:" << qPrintable(http.lastResponse().value("last-modified")); + QFAIL("Server replied with the wrong status code; see warning output"); + } +} + +void tst_QHttp::abortSender() +{ + QHttp *http = qobject_cast<QHttp *>(sender()); + if (http) + http->abort(); +} + +void tst_QHttp::abortInReadyRead() +{ + QHttp http; + http.setHost(QtNetworkSettings::serverName()); + http.get("/qtest/bigfile"); + + qRegisterMetaType<QHttpResponseHeader>(); + QSignalSpy spy(&http, SIGNAL(readyRead(QHttpResponseHeader))); + + QObject::connect(&http, SIGNAL(readyRead(QHttpResponseHeader)), this, SLOT(abortSender())); + QObject::connect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QObject::disconnect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + + QVERIFY2(!QTestEventLoop::instance().timeout(), "Network timeout"); + QVERIFY(http.state() != QHttp::Connected); + + QCOMPARE(spy.count(), 1); +} + +void tst_QHttp::abortInResponseHeaderReceived() +{ + QHttp http; + http.setHost(QtNetworkSettings::serverName()); + http.get("/qtest/bigfile"); + + qRegisterMetaType<QHttpResponseHeader>(); + QSignalSpy spy(&http, SIGNAL(readyRead(QHttpResponseHeader))); + + QObject::connect(&http, SIGNAL(responseHeaderReceived(QHttpResponseHeader)), this, SLOT(abortSender())); + QObject::connect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QObject::disconnect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + + QVERIFY2(!QTestEventLoop::instance().timeout(), "Network timeout"); + QVERIFY(http.state() != QHttp::Connected); + + QCOMPARE(spy.count(), 0); +} + +void tst_QHttp::connectionClose() +{ + // This test tries to connect to a client's server, so it is disabled. + // Every now and then, someone please run it to make sure it's not broken. + // Note: the servers might change too... + // + // This was added in response to bug 176822 + QSKIP("This test is manual - read comments in the source code", SkipAll); + + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + QHttp http; + http.setHost("www.fon.com", QHttp::ConnectionModeHttps); + http.get("/login/gateway/processLogin"); + + // another possibility: + //http.setHost("nexus.passport.com", QHttp::ConnectionModeHttps, 443); + //http.get("/rdr/pprdr.asp"); + + QObject::connect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(900); + QObject::disconnect(&http, SIGNAL(done(bool)), &QTestEventLoop::instance(), SLOT(exitLoop())); + + QVERIFY(!QTestEventLoop::instance().timeout()); +} + +void tst_QHttp::nestedEventLoop_slot(int id) +{ + if (!ids.contains(id)) + return; + QEventLoop subloop; + + // 16 seconds: fluke times out in 15 seconds, which triggers a QTcpSocket error + QTimer::singleShot(16000, &subloop, SLOT(quit())); + subloop.exec(); + + QTestEventLoop::instance().exitLoop(); +} + +void tst_QHttp::nestedEventLoop() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; + + http = new QHttp; + http->setHost(QtNetworkSettings::serverName()); + int getId = http->get("/"); + + ids.clear(); + ids << getId; + + QSignalSpy spy(http, SIGNAL(requestStarted(int))); + QSignalSpy spy2(http, SIGNAL(done(bool))); + + connect(http, SIGNAL(requestFinished(int,bool)), SLOT(nestedEventLoop_slot(int))); + QTestEventLoop::instance().enterLoop(20); + + QVERIFY2(!QTestEventLoop::instance().timeout(), "Network timeout"); + + // Find out how many signals with the first argument equalling our id were found + int spyCount = 0; + for (int i = 0; i < spy.count(); ++i) + if (spy.at(i).at(0).toInt() == getId) + ++spyCount; + + // each signal spied should have been emitted only once + QCOMPARE(spyCount, 1); + QCOMPARE(spy2.count(), 1); +} + +QTEST_MAIN(tst_QHttp) +#include "tst_qhttp.moc" diff --git a/tests/auto/qhttp/webserver/cgi-bin/retrieve_testfile.cgi b/tests/auto/qhttp/webserver/cgi-bin/retrieve_testfile.cgi new file mode 100755 index 0000000..7896c50 --- /dev/null +++ b/tests/auto/qhttp/webserver/cgi-bin/retrieve_testfile.cgi @@ -0,0 +1,6 @@ +#!/bin/sh + +echo "Content-type: text/plain"; +echo +cat testfile +echo "no file retrieved" > testfile diff --git a/tests/auto/qhttp/webserver/cgi-bin/rfc.cgi b/tests/auto/qhttp/webserver/cgi-bin/rfc.cgi new file mode 100755 index 0000000..c68688e --- /dev/null +++ b/tests/auto/qhttp/webserver/cgi-bin/rfc.cgi @@ -0,0 +1,5 @@ +#!/bin/sh + +echo "Content-type: text/plain"; +echo +cat ../rfc3252 diff --git a/tests/auto/qhttp/webserver/cgi-bin/store_testfile.cgi b/tests/auto/qhttp/webserver/cgi-bin/store_testfile.cgi new file mode 100755 index 0000000..e950f2a --- /dev/null +++ b/tests/auto/qhttp/webserver/cgi-bin/store_testfile.cgi @@ -0,0 +1,6 @@ +#!/bin/sh + +echo "Content-type: text/plain"; +echo +echo "file stored under 'testfile'" +cat > testfile diff --git a/tests/auto/qhttp/webserver/index.html b/tests/auto/qhttp/webserver/index.html new file mode 100644 index 0000000..b80c61b --- /dev/null +++ b/tests/auto/qhttp/webserver/index.html @@ -0,0 +1,899 @@ + + + + + + +Network Working Group H. Kennedy +Request for Comments: 3252 Mimezine +Category: Informational 1 April 2002 + + + Binary Lexical Octet Ad-hoc Transport + +Status of this Memo + + This memo provides information for the Internet community. It does + not specify an Internet standard of any kind. Distribution of this + memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2002). All Rights Reserved. + +Abstract + + This document defines a reformulation of IP and two transport layer + protocols (TCP and UDP) as XML applications. + +1. Introduction + +1.1. Overview + + This document describes the Binary Lexical Octet Ad-hoc Transport + (BLOAT): a reformulation of a widely-deployed network-layer protocol + (IP [RFC791]), and two associated transport layer protocols (TCP + [RFC793] and UDP [RFC768]) as XML [XML] applications. It also + describes methods for transporting BLOAT over Ethernet and IEEE 802 + networks as well as encapsulating BLOAT in IP for gatewaying BLOAT + across the public Internet. + +1.2. Motivation + + The wild popularity of XML as a basis for application-level protocols + such as the Blocks Extensible Exchange Protocol [RFC3080], the Simple + Object Access Protocol [SOAP], and Jabber [JABBER] prompted + investigation into the possibility of extending the use of XML in the + protocol stack. Using XML at both the transport and network layer in + addition to the application layer would provide for an amazing amount + of power and flexibility while removing dependencies on proprietary + and hard-to-understand binary protocols. This protocol unification + would also allow applications to use a single XML parser for all + aspects of their operation, eliminating developer time spent figuring + out the intricacies of each new protocol, and moving the hard work of + + + + +Kennedy Informational [Page 1] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + parsing to the XML toolset. The use of XML also mitigates concerns + over "network vs. host" byte ordering which is at the root of many + network application bugs. + +1.3. Relation to Existing Protocols + + The reformulations specified in this RFC follow as closely as + possible the spirit of the RFCs on which they are based, and so MAY + contain elements or attributes that would not be needed in a pure + reworking (e.g. length attributes, which are implicit in XML.) + + The layering of network and transport protocols are maintained in + this RFC despite the optimizations that could be made if the line + were somewhat blurred (i.e. merging TCP and IP into a single, larger + element in the DTD) in order to foster future use of this protocol as + a basis for reformulating other protocols (such as ICMP.) + + Other than the encoding, the behavioral aspects of each of the + existing protocols remain unchanged. Routing, address spaces, TCP + congestion control, etc. behave as specified in the extant standards. + Adapting to new standards and experimental algorithm heuristics for + improving performance will become much easier once the move to BLOAT + has been completed. + +1.4. Requirement Levels + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in BCP 14, RFC 2119 + [RFC2119]. + +2. IPoXML + + This protocol MUST be implemented to be compliant with this RFC. + IPoXML is the root protocol REQUIRED for effective use of TCPoXML + (section 3.) and higher-level application protocols. + + The DTD for this document type can be found in section 7.1. + + The routing of IPoXML can be easily implemented on hosts with an XML + parser, as the regular structure lends itself handily to parsing and + validation of the document/datagram and then processing the + destination address, TTL, and checksum before sending it on to its + next-hop. + + The reformulation of IPv4 was chosen over IPv6 [RFC2460] due to the + wider deployment of IPv4 and the fact that implementing IPv6 as XML + would have exceeded the 1500 byte Ethernet MTU. + + + +Kennedy Informational [Page 2] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + All BLOAT implementations MUST use - and specify - the UTF-8 encoding + of RFC 2279 [RFC2279]. All BLOAT document/datagrams MUST be well- + formed and include the XMLDecl. + +2.1. IP Description + + A number of items have changed (for the better) from the original IP + specification. Bit-masks, where present have been converted into + human-readable values. IP addresses are listed in their dotted- + decimal notation [RFC1123]. Length and checksum values are present + as decimal integers. + + To calculate the length and checksum fields of the IP element, a + canonicalized form of the element MUST be used. The canonical form + SHALL have no whitespace (including newline characters) between + elements and only one space character between attributes. There + SHALL NOT be a space following the last attribute in an element. + + An iterative method SHOULD be used to calculate checksums, as the + length field will vary based on the size of the checksum. + + The payload element bears special attention. Due to the character + set restrictions of XML, the payload of IP datagrams (which MAY + contain arbitrary data) MUST be encoded for transport. This RFC + REQUIRES the contents of the payload to be encoded in the base-64 + encoding of RFC 2045 [RFC2045], but removes the requirement that the + encoded output MUST be wrapped on 76-character lines. + + + + + + + + + + + + + + + + + + + + + + + + +Kennedy Informational [Page 3] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +2.2. Example Datagram + + The following is an example IPoXML datagram with an empty payload: + + <?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE ip PUBLIC "-//IETF//DTD BLOAT 1.0 IP//EN" "bloat.dtd"> + <ip> + <header length="474"> + <version value="4"/> + <tos precedence="Routine" delay="Normal" throughput="Normal" + relibility="Normal" reserved="0"/> + <total.length value="461"/> + <id value="1"/> + <flags reserved="0" df="dont" mf="last"/> + <offset value="0"/> + <ttl value="255"/> + <protocol value="6"/> + <checksum value="8707"/> + <source address="10.0.0.22"/> + <destination address="10.0.0.1"/> + <options> + <end copied="0" class="0" number="0"/> + </options> + <padding pad="0"/> + </header> + <payload> + </payload> + </ip> + +3. TCPoXML + + This protocol MUST be implemented to be compliant with this RFC. The + DTD for this document type can be found in section 7.2. + +3.1. TCP Description + + A number of items have changed from the original TCP specification. + Bit-masks, where present have been converted into human-readable + values. Length and checksum and port values are present as decimal + integers. + + To calculate the length and checksum fields of the TCP element, a + canonicalized form of the element MUST be used as in section 2.1. + + An iterative method SHOULD be used to calculate checksums as in + section 2.1. + + The payload element MUST be encoded as in section 2.1. + + + +Kennedy Informational [Page 4] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + The TCP offset element was expanded to a maximum of 255 from 16 to + allow for the increased size of the header in XML. + + TCPoXML datagrams encapsulated by IPoXML MAY omit the <?xml?> header + as well as the <!DOCTYPE> declaration. + +3.2. Example Datagram + + The following is an example TCPoXML datagram with an empty payload: + + <?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE tcp PUBLIC "-//IETF//DTD BLOAT 1.0 TCP//EN" "bloat.dtd"> + <tcp> + <tcp.header> + <src port="31415"/> + <dest port="42424"/> + <sequence number="322622954"/> + <acknowledgement number="689715995"/> + <offset number=""/> + <reserved value="0"/> + <control syn="1" ack="1"/> + <window size="1"/> + <urgent pointer="0"/> + <checksum value="2988"/> + <tcp.options> + <tcp.end kind="0"/> + </tcp.options> + <padding pad="0"/> + </tcp.header> + <payload> + </payload> + </tcp> + +4. UDPoXML + + This protocol MUST be implemented to be compliant with this RFC. The + DTD for this document type can be found in section 7.3. + +4.1. UDP Description + + A number of items have changed from the original UDP specification. + Bit-masks, where present have been converted into human-readable + values. Length and checksum and port values are present as decimal + integers. + + + + + + + +Kennedy Informational [Page 5] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + To calculate the length and checksum fields of the UDP element, a + canonicalized form of the element MUST be used as in section 2.1. An + iterative method SHOULD be used to calculate checksums as in section + 2.1. + + The payload element MUST be encoded as in section 2.1. + + UDPoXML datagrams encapsulated by IPoXML MAY omit the <?xml?> header + as well as the <!DOCTYPE> declaration. + +4.2. Example Datagram + + The following is an example UDPoXML datagram with an empty payload: + + <?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE udp PUBLIC "-//IETF//DTD BLOAT 1.0 UDP//EN" "bloat.dtd"> + <udp> + <udp.header> + <src port="31415"/> + <dest port="42424"/> + <udp.length value="143"/> + <checksum value="2988"/> + </udp.header> + <payload> + </payload> + </udp> + +5. Network Transport + + This document provides for the transmission of BLOAT datagrams over + two common families of physical layer transport. Future RFCs will + address additional transports as routing vendors catch up to the + specification, and we begin to see BLOAT routed across the Internet + backbone. + +5.1. Ethernet + + BLOAT is encapsulated in Ethernet datagrams as in [RFC894] with the + exception that the type field of the Ethernet frame MUST contain the + value 0xBEEF. The first 5 octets of the Ethernet frame payload will + be 0x3c 3f 78 6d 6c ("<?xml".) + +5.2. IEEE 802 + + BLOAT is encapsulated in IEEE 802 Networks as in [RFC1042] except + that the protocol type code for IPoXML is 0xBEEF. + + + + + +Kennedy Informational [Page 6] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +6. Gatewaying over IP + + In order to facilitate the gradual introduction of BLOAT into the + public Internet, BLOAT MAY be encapsulated in IP as in [RFC2003] to + gateway between networks that run BLOAT natively on their LANs. + +7. DTDs + + The Transport DTDs (7.2. and 7.3.) build on the definitions in the + Network DTD (7.1.) + + The DTDs are referenced by their PubidLiteral and SystemLiteral (from + [XML]) although it is understood that most IPoXML implementations + will not need to pull down the DTD, as it will normally be embedded + in the implementation, and presents something of a catch-22 if you + need to load part of your network protocol over the network. + +7.1. IPoXML DTD + + <!-- + DTD for IP over XML. + Refer to this DTD as: + + <!DOCTYPE ip PUBLIC "-//IETF//DTD BLOAT 1.0 IP//EN" "bloat.dtd"> + --> + <!-- + DTD data types: + + Digits [0..9]+ + + Precedence "NetworkControl | InternetworkControl | + CRITIC | FlashOverride | Flash | Immediate | + Priority | Routine" + + IP4Addr "dotted-decimal" notation of [RFC1123] + + Class [0..3] + + Sec "Unclassified | Confidential | EFTO | MMMM | PROG | + Restricted | Secret | Top Secret | Reserved" + + Compartments [0..65535] + + Handling [0..65535] + + TCC [0..16777216] + + --> + + + +Kennedy Informational [Page 7] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ENTITY % Digits "CDATA"> + <!ENTITY % Precedence "CDATA"> + <!ENTITY % IP4Addr "CDATA"> + <!ENTITY % Class "CDATA"> + <!ENTITY % Sec "CDATA"> + <!ENTITY % Compartments "CDATA"> + <!ENTITY % Handling "CDATA"> + <!ENTITY % TCC "CDATA"> + + <!ELEMENT ip (header, payload)> + + <!ELEMENT header (version, tos, total.length, id, flags, offset, ttl, + protocol, checksum, source, destination, options, + padding)> + <!-- length of header in 32-bit words --> + <!ATTLIST header + length %Digits; #REQUIRED> + + <!ELEMENT version EMPTY> + <!-- ip version. SHOULD be "4" --> + <!ATTLIST version + value %Digits; #REQUIRED> + + <!ELEMENT tos EMPTY> + <!ATTLIST tos + precedence %Precedence; #REQUIRED + delay (normal | low) #REQUIRED + throughput (normal | high) #REQUIRED + relibility (normal | high) #REQUIRED + reserved CDATA #FIXED "0"> + + <!ELEMENT total.length EMPTY> + <!-- + total length of datagram (header and payload) in octets, MUST be + less than 65,535 (and SHOULD be less than 1024 for IPoXML on local + ethernets). + --> + <!ATTLIST total.length + value %Digits; #REQUIRED> + + <!ELEMENT id EMPTY> + <!-- 0 <= id <= 65,535 --> + <!ATTLIST id + value %Digits; #REQUIRED> + + <!ELEMENT flags EMPTY> + <!-- df = don't fragment, mf = more fragments --> + <!ATTLIST flags + + + +Kennedy Informational [Page 8] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + reserved CDATA #FIXED "0" + df (may|dont) #REQUIRED + mf (last|more) #REQUIRED> + + <!ELEMENT offset EMPTY> + <!-- 0 <= offset <= 8192 measured in 8 octet (64-bit) chunks --> + <!ATTLIST offset + value %Digits; #REQUIRED> + + <!ELEMENT ttl EMPTY> + <!-- 0 <= ttl <= 255 --> + <!ATTLIST ttl + value %Digits; #REQUIRED> + + <!ELEMENT protocol EMPTY> + <!-- 0 <= protocol <= 255 (per IANA) --> + <!ATTLIST protocol + value %Digits; #REQUIRED> + + <!ELEMENT checksum EMPTY> + <!-- 0 <= checksum <= 65535 (over header only) --> + <!ATTLIST checksum + value %Digits; #REQUIRED> + + <!ELEMENT source EMPTY> + <!ATTLIST source + address %IP4Addr; #REQUIRED> + + <!ELEMENT destination EMPTY> + <!ATTLIST destination + address %IP4Addr; #REQUIRED> + + <!ELEMENT options ( end | noop | security | loose | strict | record + | stream | timestamp )*> + + <!ELEMENT end EMPTY> + <!ATTLIST end + copied (0|1) #REQUIRED + class CDATA #FIXED "0" + number CDATA #FIXED "0"> + + <!ELEMENT noop EMPTY> + <!ATTLIST noop + copied (0|1) #REQUIRED + class CDATA #FIXED "0" + number CDATA #FIXED "1"> + + <!ELEMENT security EMPTY> + + + +Kennedy Informational [Page 9] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ATTLIST security + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "2" + length CDATA #FIXED "11" + security %Sec; #REQUIRED + compartments %Compartments; #REQUIRED + handling %Handling; #REQUIRED + tcc %TCC; #REQUIRED> + <!ELEMENT loose (hop)+> + <!ATTLIST loose + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "3" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED> + + <!ELEMENT hop EMPTY> + <!ATTLIST hop + address %IP4Addr; #REQUIRED> + + <!ELEMENT strict (hop)+> + <!ATTLIST strict + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "9" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED> + + <!ELEMENT record (hop)+> + <!ATTLIST record + copied CDATA #FIXED "0" + class CDATA #FIXED "0" + number CDATA #FIXED "7" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED> + + <!ELEMENT stream EMPTY> + <!-- 0 <= id <= 65,535 --> + <!ATTLIST stream + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "8" + length CDATA #FIXED "4" + id %Digits; #REQUIRED> + + <!ELEMENT timestamp (tstamp)+> + <!-- 0 <= oflw <=15 --> + + + +Kennedy Informational [Page 10] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ATTLIST timestamp + copied CDATA #FIXED "0" + class CDATA #FIXED "2" + number CDATA #FIXED "4" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED + oflw %Digits; #REQUIRED + flag (0 | 1 | 3) #REQUIRED> + + <!ELEMENT tstamp EMPTY> + <!ATTLIST tstamp + time %Digits; #REQUIRED + address %IP4Addr; #IMPLIED> + <!-- + padding to bring header to 32-bit boundary. + pad MUST be "0"* + --> + <!ELEMENT padding EMPTY> + <!ATTLIST padding + pad CDATA #REQUIRED> + + <!-- payload MUST be encoded as base-64 [RFC2045], as modified + by section 2.1 of this RFC --> + <!ELEMENT payload (CDATA)> + +7.2. TCPoXML DTD + + <!-- + DTD for TCP over XML. + Refer to this DTD as: + + <!DOCTYPE tcp PUBLIC "-//IETF//DTD BLOAT 1.0 TCP//EN" "bloat.dtd"> + --> + + <!-- the pseudoheader is only included for checksum calculations --> + <!ELEMENT tcp (tcp.pseudoheader?, tcp.header, payload)> + + <!ELEMENT tcp.header (src, dest, sequence, acknowledgement, offset, + reserved, control, window, checksum, urgent, + tcp.options, padding)> + + <!ELEMENT src EMPTY> + <!-- 0 <= port <= 65,535 --> + <!ATTLIST src + port %Digits; #REQUIRED> + + <!ELEMENT dest EMPTY> + <!-- 0 <= port <= 65,535 --> + + + +Kennedy Informational [Page 11] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ATTLIST dest + port %Digits; #REQUIRED> + + <!ELEMENT sequence EMPTY> + <!-- 0 <= number <= 4294967295 --> + <!ATTLIST sequence + number %Digits; #REQUIRED> + + <!ELEMENT acknowledgement EMPTY> + <!-- 0 <= number <= 4294967295 --> + <!ATTLIST acknowledgement + number %Digits; #REQUIRED> + + <!ELEMENT offset EMPTY> + <!-- 0 <= number <= 255 --> + <!ATTLIST offset + number %Digits; #REQUIRED> + + <!ELEMENT reserved EMPTY> + <!ATTLIST reserved + value CDATA #FIXED "0"> + + <!ELEMENT control EMPTY> + <!ATTLIST control + urg (0|1) #IMPLIED + ack (0|1) #IMPLIED + psh (0|1) #IMPLIED + rst (0|1) #IMPLIED + syn (0|1) #IMPLIED + fin (0|1) #IMPLIED> + + <!ELEMENT window EMPTY> + <!-- 0 <= size <= 65,535 --> + <!ATTLIST window + size %Digits; #REQUIRED> + + <!-- + checksum as in ip, but with + the following pseudo-header added into the tcp element: + --> + <!ELEMENT tcp.pseudoheader (source, destination, protocol, + tcp.length)> + + <!-- + tcp header + data length in octets. does not include the size of + + the pseudoheader. + --> + + + +Kennedy Informational [Page 12] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ELEMENT tcp.length EMPTY> + <!ATTLIST tcp.length + value %Digits; #REQUIRED> + + <!ELEMENT urgent EMPTY> + <!-- 0 <= pointer <= 65,535 --> + <!ATTLIST urgent + pointer %Digits; #REQUIRED> + + <!ELEMENT tcp.options (tcp.end | tcp.noop | tcp.mss)+> + + <!ELEMENT tcp.end EMPTY> + <!ATTLIST tcp.end + kind CDATA #FIXED "0"> + + <!ELEMENT tcp.noop EMPTY> + <!ATTLIST tcp.noop + kind CDATA #FIXED "1"> + + <!ELEMENT tcp.mss EMPTY> + <!ATTLIST tcp.mss + kind CDATA #FIXED "2" + length CDATA #FIXED "4" + size %Digits; #REQUIRED> + +7.3. UDPoXML DTD + + <!-- + DTD for UDP over XML. + Refer to this DTD as: + + <!DOCTYPE udp PUBLIC "-//IETF//DTD BLOAT 1.0 UDP//EN" "bloat.dtd"> + --> + + <!ELEMENT udp (udp.pseudoheader?, udp.header, payload)> + + <!ELEMENT udp.header (src, dest, udp.length, checksum)> + + <!ELEMENT udp.pseudoheader (source, destination, protocol, + udp.length)> + + <!-- + udp header + data length in octets. does not include the size of + the pseudoheader. + --> + <!ELEMENT udp.length EMPTY> + <!ATTLIST udp.length + value %Digits; #REQUIRED> + + + +Kennedy Informational [Page 13] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +8. Security Considerations + + XML, as a subset of SGML, has the same security considerations as + specified in SGML Media Types [RFC1874]. Security considerations + that apply to IP, TCP and UDP also likely apply to BLOAT as it does + not attempt to correct for issues not related to message format. + +9. References + + [JABBER] Miller, J., "Jabber", draft-miller-jabber-00.txt, + February 2002. (Work in Progress) + + [RFC768] Postel, J., "User Datagram Protocol", STD 6, RFC 768, + August 1980. + + [RFC791] Postel, J., "Internet Protocol", STD 5, RFC 791, + September 1981. + + [RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC + 793, September 1981. + + [RFC894] Hornig, C., "Standard for the Transmission of IP + Datagrams over Ethernet Networks.", RFC 894, April 1984. + + [RFC1042] Postel, J. and J. Reynolds, "Standard for the + Transmission of IP Datagrams Over IEEE 802 Networks", STD + 43, RFC 1042, February 1988. + + [RFC1123] Braden, R., "Requirements for Internet Hosts - + Application and Support", RFC 1123, October 1989. + + [RFC1874] Levinson, E., "SGML Media Types", RFC 1874, December + 1995. + + [RFC2003] Perkins, C., "IP Encapsulation within IP", RFC 2003, + October 1996. + + [RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail + Extensions (MIME) Part One: Format of Internet Message + Bodies", RFC 2045, November 1996. + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO + 10646", RFC 2279, January 1998. + + + + + +Kennedy Informational [Page 14] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6 + (IPv6) Specification", RFC 2460, December 1998. + + [RFC3080] Rose, M., "The Blocks Extensible Exchange Protocol Core", + RFC 3080, March 2001. + + [SOAP] Box, D., Ehnebuske, D., Kakivaya, G., Layman, A., + Mendelsohn, N., Nielsen, H. F., Thatte, S. Winer, D., + "Simple Object Access Protocol (SOAP) 1.1" World Wide Web + Consortium Note, May 2000 http://www.w3.org/TR/SOAP/ + + [XML] Bray, T., Paoli, J., Sperberg-McQueen, C. M., "Extensible + Markup Language (XML)" World Wide Web Consortium + Recommendation REC- xml-19980210. + http://www.w3.org/TR/1998/REC-xml-19980210 + +10. Author's Address + + Hugh Kennedy + Mimezine + 1060 West Addison + Chicago, IL 60613 + USA + + EMail: kennedyh@engin.umich.edu + + + + + + + + + + + + + + + + + + + + + + + + + + +Kennedy Informational [Page 15] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +11. Full Copyright Statement + + Copyright (C) The Internet Society (2002). All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +Acknowledgement + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + + + + + + + + + + + + + + + + +Kennedy Informational [Page 16] + diff --git a/tests/auto/qhttp/webserver/rfc3252 b/tests/auto/qhttp/webserver/rfc3252 new file mode 100644 index 0000000..b80c61b --- /dev/null +++ b/tests/auto/qhttp/webserver/rfc3252 @@ -0,0 +1,899 @@ + + + + + + +Network Working Group H. Kennedy +Request for Comments: 3252 Mimezine +Category: Informational 1 April 2002 + + + Binary Lexical Octet Ad-hoc Transport + +Status of this Memo + + This memo provides information for the Internet community. It does + not specify an Internet standard of any kind. Distribution of this + memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2002). All Rights Reserved. + +Abstract + + This document defines a reformulation of IP and two transport layer + protocols (TCP and UDP) as XML applications. + +1. Introduction + +1.1. Overview + + This document describes the Binary Lexical Octet Ad-hoc Transport + (BLOAT): a reformulation of a widely-deployed network-layer protocol + (IP [RFC791]), and two associated transport layer protocols (TCP + [RFC793] and UDP [RFC768]) as XML [XML] applications. It also + describes methods for transporting BLOAT over Ethernet and IEEE 802 + networks as well as encapsulating BLOAT in IP for gatewaying BLOAT + across the public Internet. + +1.2. Motivation + + The wild popularity of XML as a basis for application-level protocols + such as the Blocks Extensible Exchange Protocol [RFC3080], the Simple + Object Access Protocol [SOAP], and Jabber [JABBER] prompted + investigation into the possibility of extending the use of XML in the + protocol stack. Using XML at both the transport and network layer in + addition to the application layer would provide for an amazing amount + of power and flexibility while removing dependencies on proprietary + and hard-to-understand binary protocols. This protocol unification + would also allow applications to use a single XML parser for all + aspects of their operation, eliminating developer time spent figuring + out the intricacies of each new protocol, and moving the hard work of + + + + +Kennedy Informational [Page 1] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + parsing to the XML toolset. The use of XML also mitigates concerns + over "network vs. host" byte ordering which is at the root of many + network application bugs. + +1.3. Relation to Existing Protocols + + The reformulations specified in this RFC follow as closely as + possible the spirit of the RFCs on which they are based, and so MAY + contain elements or attributes that would not be needed in a pure + reworking (e.g. length attributes, which are implicit in XML.) + + The layering of network and transport protocols are maintained in + this RFC despite the optimizations that could be made if the line + were somewhat blurred (i.e. merging TCP and IP into a single, larger + element in the DTD) in order to foster future use of this protocol as + a basis for reformulating other protocols (such as ICMP.) + + Other than the encoding, the behavioral aspects of each of the + existing protocols remain unchanged. Routing, address spaces, TCP + congestion control, etc. behave as specified in the extant standards. + Adapting to new standards and experimental algorithm heuristics for + improving performance will become much easier once the move to BLOAT + has been completed. + +1.4. Requirement Levels + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in BCP 14, RFC 2119 + [RFC2119]. + +2. IPoXML + + This protocol MUST be implemented to be compliant with this RFC. + IPoXML is the root protocol REQUIRED for effective use of TCPoXML + (section 3.) and higher-level application protocols. + + The DTD for this document type can be found in section 7.1. + + The routing of IPoXML can be easily implemented on hosts with an XML + parser, as the regular structure lends itself handily to parsing and + validation of the document/datagram and then processing the + destination address, TTL, and checksum before sending it on to its + next-hop. + + The reformulation of IPv4 was chosen over IPv6 [RFC2460] due to the + wider deployment of IPv4 and the fact that implementing IPv6 as XML + would have exceeded the 1500 byte Ethernet MTU. + + + +Kennedy Informational [Page 2] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + All BLOAT implementations MUST use - and specify - the UTF-8 encoding + of RFC 2279 [RFC2279]. All BLOAT document/datagrams MUST be well- + formed and include the XMLDecl. + +2.1. IP Description + + A number of items have changed (for the better) from the original IP + specification. Bit-masks, where present have been converted into + human-readable values. IP addresses are listed in their dotted- + decimal notation [RFC1123]. Length and checksum values are present + as decimal integers. + + To calculate the length and checksum fields of the IP element, a + canonicalized form of the element MUST be used. The canonical form + SHALL have no whitespace (including newline characters) between + elements and only one space character between attributes. There + SHALL NOT be a space following the last attribute in an element. + + An iterative method SHOULD be used to calculate checksums, as the + length field will vary based on the size of the checksum. + + The payload element bears special attention. Due to the character + set restrictions of XML, the payload of IP datagrams (which MAY + contain arbitrary data) MUST be encoded for transport. This RFC + REQUIRES the contents of the payload to be encoded in the base-64 + encoding of RFC 2045 [RFC2045], but removes the requirement that the + encoded output MUST be wrapped on 76-character lines. + + + + + + + + + + + + + + + + + + + + + + + + +Kennedy Informational [Page 3] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +2.2. Example Datagram + + The following is an example IPoXML datagram with an empty payload: + + <?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE ip PUBLIC "-//IETF//DTD BLOAT 1.0 IP//EN" "bloat.dtd"> + <ip> + <header length="474"> + <version value="4"/> + <tos precedence="Routine" delay="Normal" throughput="Normal" + relibility="Normal" reserved="0"/> + <total.length value="461"/> + <id value="1"/> + <flags reserved="0" df="dont" mf="last"/> + <offset value="0"/> + <ttl value="255"/> + <protocol value="6"/> + <checksum value="8707"/> + <source address="10.0.0.22"/> + <destination address="10.0.0.1"/> + <options> + <end copied="0" class="0" number="0"/> + </options> + <padding pad="0"/> + </header> + <payload> + </payload> + </ip> + +3. TCPoXML + + This protocol MUST be implemented to be compliant with this RFC. The + DTD for this document type can be found in section 7.2. + +3.1. TCP Description + + A number of items have changed from the original TCP specification. + Bit-masks, where present have been converted into human-readable + values. Length and checksum and port values are present as decimal + integers. + + To calculate the length and checksum fields of the TCP element, a + canonicalized form of the element MUST be used as in section 2.1. + + An iterative method SHOULD be used to calculate checksums as in + section 2.1. + + The payload element MUST be encoded as in section 2.1. + + + +Kennedy Informational [Page 4] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + The TCP offset element was expanded to a maximum of 255 from 16 to + allow for the increased size of the header in XML. + + TCPoXML datagrams encapsulated by IPoXML MAY omit the <?xml?> header + as well as the <!DOCTYPE> declaration. + +3.2. Example Datagram + + The following is an example TCPoXML datagram with an empty payload: + + <?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE tcp PUBLIC "-//IETF//DTD BLOAT 1.0 TCP//EN" "bloat.dtd"> + <tcp> + <tcp.header> + <src port="31415"/> + <dest port="42424"/> + <sequence number="322622954"/> + <acknowledgement number="689715995"/> + <offset number=""/> + <reserved value="0"/> + <control syn="1" ack="1"/> + <window size="1"/> + <urgent pointer="0"/> + <checksum value="2988"/> + <tcp.options> + <tcp.end kind="0"/> + </tcp.options> + <padding pad="0"/> + </tcp.header> + <payload> + </payload> + </tcp> + +4. UDPoXML + + This protocol MUST be implemented to be compliant with this RFC. The + DTD for this document type can be found in section 7.3. + +4.1. UDP Description + + A number of items have changed from the original UDP specification. + Bit-masks, where present have been converted into human-readable + values. Length and checksum and port values are present as decimal + integers. + + + + + + + +Kennedy Informational [Page 5] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + To calculate the length and checksum fields of the UDP element, a + canonicalized form of the element MUST be used as in section 2.1. An + iterative method SHOULD be used to calculate checksums as in section + 2.1. + + The payload element MUST be encoded as in section 2.1. + + UDPoXML datagrams encapsulated by IPoXML MAY omit the <?xml?> header + as well as the <!DOCTYPE> declaration. + +4.2. Example Datagram + + The following is an example UDPoXML datagram with an empty payload: + + <?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE udp PUBLIC "-//IETF//DTD BLOAT 1.0 UDP//EN" "bloat.dtd"> + <udp> + <udp.header> + <src port="31415"/> + <dest port="42424"/> + <udp.length value="143"/> + <checksum value="2988"/> + </udp.header> + <payload> + </payload> + </udp> + +5. Network Transport + + This document provides for the transmission of BLOAT datagrams over + two common families of physical layer transport. Future RFCs will + address additional transports as routing vendors catch up to the + specification, and we begin to see BLOAT routed across the Internet + backbone. + +5.1. Ethernet + + BLOAT is encapsulated in Ethernet datagrams as in [RFC894] with the + exception that the type field of the Ethernet frame MUST contain the + value 0xBEEF. The first 5 octets of the Ethernet frame payload will + be 0x3c 3f 78 6d 6c ("<?xml".) + +5.2. IEEE 802 + + BLOAT is encapsulated in IEEE 802 Networks as in [RFC1042] except + that the protocol type code for IPoXML is 0xBEEF. + + + + + +Kennedy Informational [Page 6] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +6. Gatewaying over IP + + In order to facilitate the gradual introduction of BLOAT into the + public Internet, BLOAT MAY be encapsulated in IP as in [RFC2003] to + gateway between networks that run BLOAT natively on their LANs. + +7. DTDs + + The Transport DTDs (7.2. and 7.3.) build on the definitions in the + Network DTD (7.1.) + + The DTDs are referenced by their PubidLiteral and SystemLiteral (from + [XML]) although it is understood that most IPoXML implementations + will not need to pull down the DTD, as it will normally be embedded + in the implementation, and presents something of a catch-22 if you + need to load part of your network protocol over the network. + +7.1. IPoXML DTD + + <!-- + DTD for IP over XML. + Refer to this DTD as: + + <!DOCTYPE ip PUBLIC "-//IETF//DTD BLOAT 1.0 IP//EN" "bloat.dtd"> + --> + <!-- + DTD data types: + + Digits [0..9]+ + + Precedence "NetworkControl | InternetworkControl | + CRITIC | FlashOverride | Flash | Immediate | + Priority | Routine" + + IP4Addr "dotted-decimal" notation of [RFC1123] + + Class [0..3] + + Sec "Unclassified | Confidential | EFTO | MMMM | PROG | + Restricted | Secret | Top Secret | Reserved" + + Compartments [0..65535] + + Handling [0..65535] + + TCC [0..16777216] + + --> + + + +Kennedy Informational [Page 7] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ENTITY % Digits "CDATA"> + <!ENTITY % Precedence "CDATA"> + <!ENTITY % IP4Addr "CDATA"> + <!ENTITY % Class "CDATA"> + <!ENTITY % Sec "CDATA"> + <!ENTITY % Compartments "CDATA"> + <!ENTITY % Handling "CDATA"> + <!ENTITY % TCC "CDATA"> + + <!ELEMENT ip (header, payload)> + + <!ELEMENT header (version, tos, total.length, id, flags, offset, ttl, + protocol, checksum, source, destination, options, + padding)> + <!-- length of header in 32-bit words --> + <!ATTLIST header + length %Digits; #REQUIRED> + + <!ELEMENT version EMPTY> + <!-- ip version. SHOULD be "4" --> + <!ATTLIST version + value %Digits; #REQUIRED> + + <!ELEMENT tos EMPTY> + <!ATTLIST tos + precedence %Precedence; #REQUIRED + delay (normal | low) #REQUIRED + throughput (normal | high) #REQUIRED + relibility (normal | high) #REQUIRED + reserved CDATA #FIXED "0"> + + <!ELEMENT total.length EMPTY> + <!-- + total length of datagram (header and payload) in octets, MUST be + less than 65,535 (and SHOULD be less than 1024 for IPoXML on local + ethernets). + --> + <!ATTLIST total.length + value %Digits; #REQUIRED> + + <!ELEMENT id EMPTY> + <!-- 0 <= id <= 65,535 --> + <!ATTLIST id + value %Digits; #REQUIRED> + + <!ELEMENT flags EMPTY> + <!-- df = don't fragment, mf = more fragments --> + <!ATTLIST flags + + + +Kennedy Informational [Page 8] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + reserved CDATA #FIXED "0" + df (may|dont) #REQUIRED + mf (last|more) #REQUIRED> + + <!ELEMENT offset EMPTY> + <!-- 0 <= offset <= 8192 measured in 8 octet (64-bit) chunks --> + <!ATTLIST offset + value %Digits; #REQUIRED> + + <!ELEMENT ttl EMPTY> + <!-- 0 <= ttl <= 255 --> + <!ATTLIST ttl + value %Digits; #REQUIRED> + + <!ELEMENT protocol EMPTY> + <!-- 0 <= protocol <= 255 (per IANA) --> + <!ATTLIST protocol + value %Digits; #REQUIRED> + + <!ELEMENT checksum EMPTY> + <!-- 0 <= checksum <= 65535 (over header only) --> + <!ATTLIST checksum + value %Digits; #REQUIRED> + + <!ELEMENT source EMPTY> + <!ATTLIST source + address %IP4Addr; #REQUIRED> + + <!ELEMENT destination EMPTY> + <!ATTLIST destination + address %IP4Addr; #REQUIRED> + + <!ELEMENT options ( end | noop | security | loose | strict | record + | stream | timestamp )*> + + <!ELEMENT end EMPTY> + <!ATTLIST end + copied (0|1) #REQUIRED + class CDATA #FIXED "0" + number CDATA #FIXED "0"> + + <!ELEMENT noop EMPTY> + <!ATTLIST noop + copied (0|1) #REQUIRED + class CDATA #FIXED "0" + number CDATA #FIXED "1"> + + <!ELEMENT security EMPTY> + + + +Kennedy Informational [Page 9] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ATTLIST security + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "2" + length CDATA #FIXED "11" + security %Sec; #REQUIRED + compartments %Compartments; #REQUIRED + handling %Handling; #REQUIRED + tcc %TCC; #REQUIRED> + <!ELEMENT loose (hop)+> + <!ATTLIST loose + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "3" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED> + + <!ELEMENT hop EMPTY> + <!ATTLIST hop + address %IP4Addr; #REQUIRED> + + <!ELEMENT strict (hop)+> + <!ATTLIST strict + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "9" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED> + + <!ELEMENT record (hop)+> + <!ATTLIST record + copied CDATA #FIXED "0" + class CDATA #FIXED "0" + number CDATA #FIXED "7" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED> + + <!ELEMENT stream EMPTY> + <!-- 0 <= id <= 65,535 --> + <!ATTLIST stream + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "8" + length CDATA #FIXED "4" + id %Digits; #REQUIRED> + + <!ELEMENT timestamp (tstamp)+> + <!-- 0 <= oflw <=15 --> + + + +Kennedy Informational [Page 10] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ATTLIST timestamp + copied CDATA #FIXED "0" + class CDATA #FIXED "2" + number CDATA #FIXED "4" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED + oflw %Digits; #REQUIRED + flag (0 | 1 | 3) #REQUIRED> + + <!ELEMENT tstamp EMPTY> + <!ATTLIST tstamp + time %Digits; #REQUIRED + address %IP4Addr; #IMPLIED> + <!-- + padding to bring header to 32-bit boundary. + pad MUST be "0"* + --> + <!ELEMENT padding EMPTY> + <!ATTLIST padding + pad CDATA #REQUIRED> + + <!-- payload MUST be encoded as base-64 [RFC2045], as modified + by section 2.1 of this RFC --> + <!ELEMENT payload (CDATA)> + +7.2. TCPoXML DTD + + <!-- + DTD for TCP over XML. + Refer to this DTD as: + + <!DOCTYPE tcp PUBLIC "-//IETF//DTD BLOAT 1.0 TCP//EN" "bloat.dtd"> + --> + + <!-- the pseudoheader is only included for checksum calculations --> + <!ELEMENT tcp (tcp.pseudoheader?, tcp.header, payload)> + + <!ELEMENT tcp.header (src, dest, sequence, acknowledgement, offset, + reserved, control, window, checksum, urgent, + tcp.options, padding)> + + <!ELEMENT src EMPTY> + <!-- 0 <= port <= 65,535 --> + <!ATTLIST src + port %Digits; #REQUIRED> + + <!ELEMENT dest EMPTY> + <!-- 0 <= port <= 65,535 --> + + + +Kennedy Informational [Page 11] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ATTLIST dest + port %Digits; #REQUIRED> + + <!ELEMENT sequence EMPTY> + <!-- 0 <= number <= 4294967295 --> + <!ATTLIST sequence + number %Digits; #REQUIRED> + + <!ELEMENT acknowledgement EMPTY> + <!-- 0 <= number <= 4294967295 --> + <!ATTLIST acknowledgement + number %Digits; #REQUIRED> + + <!ELEMENT offset EMPTY> + <!-- 0 <= number <= 255 --> + <!ATTLIST offset + number %Digits; #REQUIRED> + + <!ELEMENT reserved EMPTY> + <!ATTLIST reserved + value CDATA #FIXED "0"> + + <!ELEMENT control EMPTY> + <!ATTLIST control + urg (0|1) #IMPLIED + ack (0|1) #IMPLIED + psh (0|1) #IMPLIED + rst (0|1) #IMPLIED + syn (0|1) #IMPLIED + fin (0|1) #IMPLIED> + + <!ELEMENT window EMPTY> + <!-- 0 <= size <= 65,535 --> + <!ATTLIST window + size %Digits; #REQUIRED> + + <!-- + checksum as in ip, but with + the following pseudo-header added into the tcp element: + --> + <!ELEMENT tcp.pseudoheader (source, destination, protocol, + tcp.length)> + + <!-- + tcp header + data length in octets. does not include the size of + + the pseudoheader. + --> + + + +Kennedy Informational [Page 12] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ELEMENT tcp.length EMPTY> + <!ATTLIST tcp.length + value %Digits; #REQUIRED> + + <!ELEMENT urgent EMPTY> + <!-- 0 <= pointer <= 65,535 --> + <!ATTLIST urgent + pointer %Digits; #REQUIRED> + + <!ELEMENT tcp.options (tcp.end | tcp.noop | tcp.mss)+> + + <!ELEMENT tcp.end EMPTY> + <!ATTLIST tcp.end + kind CDATA #FIXED "0"> + + <!ELEMENT tcp.noop EMPTY> + <!ATTLIST tcp.noop + kind CDATA #FIXED "1"> + + <!ELEMENT tcp.mss EMPTY> + <!ATTLIST tcp.mss + kind CDATA #FIXED "2" + length CDATA #FIXED "4" + size %Digits; #REQUIRED> + +7.3. UDPoXML DTD + + <!-- + DTD for UDP over XML. + Refer to this DTD as: + + <!DOCTYPE udp PUBLIC "-//IETF//DTD BLOAT 1.0 UDP//EN" "bloat.dtd"> + --> + + <!ELEMENT udp (udp.pseudoheader?, udp.header, payload)> + + <!ELEMENT udp.header (src, dest, udp.length, checksum)> + + <!ELEMENT udp.pseudoheader (source, destination, protocol, + udp.length)> + + <!-- + udp header + data length in octets. does not include the size of + the pseudoheader. + --> + <!ELEMENT udp.length EMPTY> + <!ATTLIST udp.length + value %Digits; #REQUIRED> + + + +Kennedy Informational [Page 13] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +8. Security Considerations + + XML, as a subset of SGML, has the same security considerations as + specified in SGML Media Types [RFC1874]. Security considerations + that apply to IP, TCP and UDP also likely apply to BLOAT as it does + not attempt to correct for issues not related to message format. + +9. References + + [JABBER] Miller, J., "Jabber", draft-miller-jabber-00.txt, + February 2002. (Work in Progress) + + [RFC768] Postel, J., "User Datagram Protocol", STD 6, RFC 768, + August 1980. + + [RFC791] Postel, J., "Internet Protocol", STD 5, RFC 791, + September 1981. + + [RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC + 793, September 1981. + + [RFC894] Hornig, C., "Standard for the Transmission of IP + Datagrams over Ethernet Networks.", RFC 894, April 1984. + + [RFC1042] Postel, J. and J. Reynolds, "Standard for the + Transmission of IP Datagrams Over IEEE 802 Networks", STD + 43, RFC 1042, February 1988. + + [RFC1123] Braden, R., "Requirements for Internet Hosts - + Application and Support", RFC 1123, October 1989. + + [RFC1874] Levinson, E., "SGML Media Types", RFC 1874, December + 1995. + + [RFC2003] Perkins, C., "IP Encapsulation within IP", RFC 2003, + October 1996. + + [RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail + Extensions (MIME) Part One: Format of Internet Message + Bodies", RFC 2045, November 1996. + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO + 10646", RFC 2279, January 1998. + + + + + +Kennedy Informational [Page 14] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6 + (IPv6) Specification", RFC 2460, December 1998. + + [RFC3080] Rose, M., "The Blocks Extensible Exchange Protocol Core", + RFC 3080, March 2001. + + [SOAP] Box, D., Ehnebuske, D., Kakivaya, G., Layman, A., + Mendelsohn, N., Nielsen, H. F., Thatte, S. Winer, D., + "Simple Object Access Protocol (SOAP) 1.1" World Wide Web + Consortium Note, May 2000 http://www.w3.org/TR/SOAP/ + + [XML] Bray, T., Paoli, J., Sperberg-McQueen, C. M., "Extensible + Markup Language (XML)" World Wide Web Consortium + Recommendation REC- xml-19980210. + http://www.w3.org/TR/1998/REC-xml-19980210 + +10. Author's Address + + Hugh Kennedy + Mimezine + 1060 West Addison + Chicago, IL 60613 + USA + + EMail: kennedyh@engin.umich.edu + + + + + + + + + + + + + + + + + + + + + + + + + + +Kennedy Informational [Page 15] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +11. Full Copyright Statement + + Copyright (C) The Internet Society (2002). All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +Acknowledgement + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + + + + + + + + + + + + + + + + +Kennedy Informational [Page 16] + diff --git a/tests/auto/qhttp/webserver/rfc3252.txt b/tests/auto/qhttp/webserver/rfc3252.txt new file mode 100644 index 0000000..b80c61b --- /dev/null +++ b/tests/auto/qhttp/webserver/rfc3252.txt @@ -0,0 +1,899 @@ + + + + + + +Network Working Group H. Kennedy +Request for Comments: 3252 Mimezine +Category: Informational 1 April 2002 + + + Binary Lexical Octet Ad-hoc Transport + +Status of this Memo + + This memo provides information for the Internet community. It does + not specify an Internet standard of any kind. Distribution of this + memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2002). All Rights Reserved. + +Abstract + + This document defines a reformulation of IP and two transport layer + protocols (TCP and UDP) as XML applications. + +1. Introduction + +1.1. Overview + + This document describes the Binary Lexical Octet Ad-hoc Transport + (BLOAT): a reformulation of a widely-deployed network-layer protocol + (IP [RFC791]), and two associated transport layer protocols (TCP + [RFC793] and UDP [RFC768]) as XML [XML] applications. It also + describes methods for transporting BLOAT over Ethernet and IEEE 802 + networks as well as encapsulating BLOAT in IP for gatewaying BLOAT + across the public Internet. + +1.2. Motivation + + The wild popularity of XML as a basis for application-level protocols + such as the Blocks Extensible Exchange Protocol [RFC3080], the Simple + Object Access Protocol [SOAP], and Jabber [JABBER] prompted + investigation into the possibility of extending the use of XML in the + protocol stack. Using XML at both the transport and network layer in + addition to the application layer would provide for an amazing amount + of power and flexibility while removing dependencies on proprietary + and hard-to-understand binary protocols. This protocol unification + would also allow applications to use a single XML parser for all + aspects of their operation, eliminating developer time spent figuring + out the intricacies of each new protocol, and moving the hard work of + + + + +Kennedy Informational [Page 1] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + parsing to the XML toolset. The use of XML also mitigates concerns + over "network vs. host" byte ordering which is at the root of many + network application bugs. + +1.3. Relation to Existing Protocols + + The reformulations specified in this RFC follow as closely as + possible the spirit of the RFCs on which they are based, and so MAY + contain elements or attributes that would not be needed in a pure + reworking (e.g. length attributes, which are implicit in XML.) + + The layering of network and transport protocols are maintained in + this RFC despite the optimizations that could be made if the line + were somewhat blurred (i.e. merging TCP and IP into a single, larger + element in the DTD) in order to foster future use of this protocol as + a basis for reformulating other protocols (such as ICMP.) + + Other than the encoding, the behavioral aspects of each of the + existing protocols remain unchanged. Routing, address spaces, TCP + congestion control, etc. behave as specified in the extant standards. + Adapting to new standards and experimental algorithm heuristics for + improving performance will become much easier once the move to BLOAT + has been completed. + +1.4. Requirement Levels + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in BCP 14, RFC 2119 + [RFC2119]. + +2. IPoXML + + This protocol MUST be implemented to be compliant with this RFC. + IPoXML is the root protocol REQUIRED for effective use of TCPoXML + (section 3.) and higher-level application protocols. + + The DTD for this document type can be found in section 7.1. + + The routing of IPoXML can be easily implemented on hosts with an XML + parser, as the regular structure lends itself handily to parsing and + validation of the document/datagram and then processing the + destination address, TTL, and checksum before sending it on to its + next-hop. + + The reformulation of IPv4 was chosen over IPv6 [RFC2460] due to the + wider deployment of IPv4 and the fact that implementing IPv6 as XML + would have exceeded the 1500 byte Ethernet MTU. + + + +Kennedy Informational [Page 2] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + All BLOAT implementations MUST use - and specify - the UTF-8 encoding + of RFC 2279 [RFC2279]. All BLOAT document/datagrams MUST be well- + formed and include the XMLDecl. + +2.1. IP Description + + A number of items have changed (for the better) from the original IP + specification. Bit-masks, where present have been converted into + human-readable values. IP addresses are listed in their dotted- + decimal notation [RFC1123]. Length and checksum values are present + as decimal integers. + + To calculate the length and checksum fields of the IP element, a + canonicalized form of the element MUST be used. The canonical form + SHALL have no whitespace (including newline characters) between + elements and only one space character between attributes. There + SHALL NOT be a space following the last attribute in an element. + + An iterative method SHOULD be used to calculate checksums, as the + length field will vary based on the size of the checksum. + + The payload element bears special attention. Due to the character + set restrictions of XML, the payload of IP datagrams (which MAY + contain arbitrary data) MUST be encoded for transport. This RFC + REQUIRES the contents of the payload to be encoded in the base-64 + encoding of RFC 2045 [RFC2045], but removes the requirement that the + encoded output MUST be wrapped on 76-character lines. + + + + + + + + + + + + + + + + + + + + + + + + +Kennedy Informational [Page 3] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +2.2. Example Datagram + + The following is an example IPoXML datagram with an empty payload: + + <?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE ip PUBLIC "-//IETF//DTD BLOAT 1.0 IP//EN" "bloat.dtd"> + <ip> + <header length="474"> + <version value="4"/> + <tos precedence="Routine" delay="Normal" throughput="Normal" + relibility="Normal" reserved="0"/> + <total.length value="461"/> + <id value="1"/> + <flags reserved="0" df="dont" mf="last"/> + <offset value="0"/> + <ttl value="255"/> + <protocol value="6"/> + <checksum value="8707"/> + <source address="10.0.0.22"/> + <destination address="10.0.0.1"/> + <options> + <end copied="0" class="0" number="0"/> + </options> + <padding pad="0"/> + </header> + <payload> + </payload> + </ip> + +3. TCPoXML + + This protocol MUST be implemented to be compliant with this RFC. The + DTD for this document type can be found in section 7.2. + +3.1. TCP Description + + A number of items have changed from the original TCP specification. + Bit-masks, where present have been converted into human-readable + values. Length and checksum and port values are present as decimal + integers. + + To calculate the length and checksum fields of the TCP element, a + canonicalized form of the element MUST be used as in section 2.1. + + An iterative method SHOULD be used to calculate checksums as in + section 2.1. + + The payload element MUST be encoded as in section 2.1. + + + +Kennedy Informational [Page 4] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + The TCP offset element was expanded to a maximum of 255 from 16 to + allow for the increased size of the header in XML. + + TCPoXML datagrams encapsulated by IPoXML MAY omit the <?xml?> header + as well as the <!DOCTYPE> declaration. + +3.2. Example Datagram + + The following is an example TCPoXML datagram with an empty payload: + + <?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE tcp PUBLIC "-//IETF//DTD BLOAT 1.0 TCP//EN" "bloat.dtd"> + <tcp> + <tcp.header> + <src port="31415"/> + <dest port="42424"/> + <sequence number="322622954"/> + <acknowledgement number="689715995"/> + <offset number=""/> + <reserved value="0"/> + <control syn="1" ack="1"/> + <window size="1"/> + <urgent pointer="0"/> + <checksum value="2988"/> + <tcp.options> + <tcp.end kind="0"/> + </tcp.options> + <padding pad="0"/> + </tcp.header> + <payload> + </payload> + </tcp> + +4. UDPoXML + + This protocol MUST be implemented to be compliant with this RFC. The + DTD for this document type can be found in section 7.3. + +4.1. UDP Description + + A number of items have changed from the original UDP specification. + Bit-masks, where present have been converted into human-readable + values. Length and checksum and port values are present as decimal + integers. + + + + + + + +Kennedy Informational [Page 5] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + To calculate the length and checksum fields of the UDP element, a + canonicalized form of the element MUST be used as in section 2.1. An + iterative method SHOULD be used to calculate checksums as in section + 2.1. + + The payload element MUST be encoded as in section 2.1. + + UDPoXML datagrams encapsulated by IPoXML MAY omit the <?xml?> header + as well as the <!DOCTYPE> declaration. + +4.2. Example Datagram + + The following is an example UDPoXML datagram with an empty payload: + + <?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE udp PUBLIC "-//IETF//DTD BLOAT 1.0 UDP//EN" "bloat.dtd"> + <udp> + <udp.header> + <src port="31415"/> + <dest port="42424"/> + <udp.length value="143"/> + <checksum value="2988"/> + </udp.header> + <payload> + </payload> + </udp> + +5. Network Transport + + This document provides for the transmission of BLOAT datagrams over + two common families of physical layer transport. Future RFCs will + address additional transports as routing vendors catch up to the + specification, and we begin to see BLOAT routed across the Internet + backbone. + +5.1. Ethernet + + BLOAT is encapsulated in Ethernet datagrams as in [RFC894] with the + exception that the type field of the Ethernet frame MUST contain the + value 0xBEEF. The first 5 octets of the Ethernet frame payload will + be 0x3c 3f 78 6d 6c ("<?xml".) + +5.2. IEEE 802 + + BLOAT is encapsulated in IEEE 802 Networks as in [RFC1042] except + that the protocol type code for IPoXML is 0xBEEF. + + + + + +Kennedy Informational [Page 6] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +6. Gatewaying over IP + + In order to facilitate the gradual introduction of BLOAT into the + public Internet, BLOAT MAY be encapsulated in IP as in [RFC2003] to + gateway between networks that run BLOAT natively on their LANs. + +7. DTDs + + The Transport DTDs (7.2. and 7.3.) build on the definitions in the + Network DTD (7.1.) + + The DTDs are referenced by their PubidLiteral and SystemLiteral (from + [XML]) although it is understood that most IPoXML implementations + will not need to pull down the DTD, as it will normally be embedded + in the implementation, and presents something of a catch-22 if you + need to load part of your network protocol over the network. + +7.1. IPoXML DTD + + <!-- + DTD for IP over XML. + Refer to this DTD as: + + <!DOCTYPE ip PUBLIC "-//IETF//DTD BLOAT 1.0 IP//EN" "bloat.dtd"> + --> + <!-- + DTD data types: + + Digits [0..9]+ + + Precedence "NetworkControl | InternetworkControl | + CRITIC | FlashOverride | Flash | Immediate | + Priority | Routine" + + IP4Addr "dotted-decimal" notation of [RFC1123] + + Class [0..3] + + Sec "Unclassified | Confidential | EFTO | MMMM | PROG | + Restricted | Secret | Top Secret | Reserved" + + Compartments [0..65535] + + Handling [0..65535] + + TCC [0..16777216] + + --> + + + +Kennedy Informational [Page 7] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ENTITY % Digits "CDATA"> + <!ENTITY % Precedence "CDATA"> + <!ENTITY % IP4Addr "CDATA"> + <!ENTITY % Class "CDATA"> + <!ENTITY % Sec "CDATA"> + <!ENTITY % Compartments "CDATA"> + <!ENTITY % Handling "CDATA"> + <!ENTITY % TCC "CDATA"> + + <!ELEMENT ip (header, payload)> + + <!ELEMENT header (version, tos, total.length, id, flags, offset, ttl, + protocol, checksum, source, destination, options, + padding)> + <!-- length of header in 32-bit words --> + <!ATTLIST header + length %Digits; #REQUIRED> + + <!ELEMENT version EMPTY> + <!-- ip version. SHOULD be "4" --> + <!ATTLIST version + value %Digits; #REQUIRED> + + <!ELEMENT tos EMPTY> + <!ATTLIST tos + precedence %Precedence; #REQUIRED + delay (normal | low) #REQUIRED + throughput (normal | high) #REQUIRED + relibility (normal | high) #REQUIRED + reserved CDATA #FIXED "0"> + + <!ELEMENT total.length EMPTY> + <!-- + total length of datagram (header and payload) in octets, MUST be + less than 65,535 (and SHOULD be less than 1024 for IPoXML on local + ethernets). + --> + <!ATTLIST total.length + value %Digits; #REQUIRED> + + <!ELEMENT id EMPTY> + <!-- 0 <= id <= 65,535 --> + <!ATTLIST id + value %Digits; #REQUIRED> + + <!ELEMENT flags EMPTY> + <!-- df = don't fragment, mf = more fragments --> + <!ATTLIST flags + + + +Kennedy Informational [Page 8] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + reserved CDATA #FIXED "0" + df (may|dont) #REQUIRED + mf (last|more) #REQUIRED> + + <!ELEMENT offset EMPTY> + <!-- 0 <= offset <= 8192 measured in 8 octet (64-bit) chunks --> + <!ATTLIST offset + value %Digits; #REQUIRED> + + <!ELEMENT ttl EMPTY> + <!-- 0 <= ttl <= 255 --> + <!ATTLIST ttl + value %Digits; #REQUIRED> + + <!ELEMENT protocol EMPTY> + <!-- 0 <= protocol <= 255 (per IANA) --> + <!ATTLIST protocol + value %Digits; #REQUIRED> + + <!ELEMENT checksum EMPTY> + <!-- 0 <= checksum <= 65535 (over header only) --> + <!ATTLIST checksum + value %Digits; #REQUIRED> + + <!ELEMENT source EMPTY> + <!ATTLIST source + address %IP4Addr; #REQUIRED> + + <!ELEMENT destination EMPTY> + <!ATTLIST destination + address %IP4Addr; #REQUIRED> + + <!ELEMENT options ( end | noop | security | loose | strict | record + | stream | timestamp )*> + + <!ELEMENT end EMPTY> + <!ATTLIST end + copied (0|1) #REQUIRED + class CDATA #FIXED "0" + number CDATA #FIXED "0"> + + <!ELEMENT noop EMPTY> + <!ATTLIST noop + copied (0|1) #REQUIRED + class CDATA #FIXED "0" + number CDATA #FIXED "1"> + + <!ELEMENT security EMPTY> + + + +Kennedy Informational [Page 9] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ATTLIST security + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "2" + length CDATA #FIXED "11" + security %Sec; #REQUIRED + compartments %Compartments; #REQUIRED + handling %Handling; #REQUIRED + tcc %TCC; #REQUIRED> + <!ELEMENT loose (hop)+> + <!ATTLIST loose + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "3" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED> + + <!ELEMENT hop EMPTY> + <!ATTLIST hop + address %IP4Addr; #REQUIRED> + + <!ELEMENT strict (hop)+> + <!ATTLIST strict + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "9" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED> + + <!ELEMENT record (hop)+> + <!ATTLIST record + copied CDATA #FIXED "0" + class CDATA #FIXED "0" + number CDATA #FIXED "7" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED> + + <!ELEMENT stream EMPTY> + <!-- 0 <= id <= 65,535 --> + <!ATTLIST stream + copied CDATA #FIXED "1" + class CDATA #FIXED "0" + number CDATA #FIXED "8" + length CDATA #FIXED "4" + id %Digits; #REQUIRED> + + <!ELEMENT timestamp (tstamp)+> + <!-- 0 <= oflw <=15 --> + + + +Kennedy Informational [Page 10] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ATTLIST timestamp + copied CDATA #FIXED "0" + class CDATA #FIXED "2" + number CDATA #FIXED "4" + length %Digits; #REQUIRED + pointer %Digits; #REQUIRED + oflw %Digits; #REQUIRED + flag (0 | 1 | 3) #REQUIRED> + + <!ELEMENT tstamp EMPTY> + <!ATTLIST tstamp + time %Digits; #REQUIRED + address %IP4Addr; #IMPLIED> + <!-- + padding to bring header to 32-bit boundary. + pad MUST be "0"* + --> + <!ELEMENT padding EMPTY> + <!ATTLIST padding + pad CDATA #REQUIRED> + + <!-- payload MUST be encoded as base-64 [RFC2045], as modified + by section 2.1 of this RFC --> + <!ELEMENT payload (CDATA)> + +7.2. TCPoXML DTD + + <!-- + DTD for TCP over XML. + Refer to this DTD as: + + <!DOCTYPE tcp PUBLIC "-//IETF//DTD BLOAT 1.0 TCP//EN" "bloat.dtd"> + --> + + <!-- the pseudoheader is only included for checksum calculations --> + <!ELEMENT tcp (tcp.pseudoheader?, tcp.header, payload)> + + <!ELEMENT tcp.header (src, dest, sequence, acknowledgement, offset, + reserved, control, window, checksum, urgent, + tcp.options, padding)> + + <!ELEMENT src EMPTY> + <!-- 0 <= port <= 65,535 --> + <!ATTLIST src + port %Digits; #REQUIRED> + + <!ELEMENT dest EMPTY> + <!-- 0 <= port <= 65,535 --> + + + +Kennedy Informational [Page 11] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ATTLIST dest + port %Digits; #REQUIRED> + + <!ELEMENT sequence EMPTY> + <!-- 0 <= number <= 4294967295 --> + <!ATTLIST sequence + number %Digits; #REQUIRED> + + <!ELEMENT acknowledgement EMPTY> + <!-- 0 <= number <= 4294967295 --> + <!ATTLIST acknowledgement + number %Digits; #REQUIRED> + + <!ELEMENT offset EMPTY> + <!-- 0 <= number <= 255 --> + <!ATTLIST offset + number %Digits; #REQUIRED> + + <!ELEMENT reserved EMPTY> + <!ATTLIST reserved + value CDATA #FIXED "0"> + + <!ELEMENT control EMPTY> + <!ATTLIST control + urg (0|1) #IMPLIED + ack (0|1) #IMPLIED + psh (0|1) #IMPLIED + rst (0|1) #IMPLIED + syn (0|1) #IMPLIED + fin (0|1) #IMPLIED> + + <!ELEMENT window EMPTY> + <!-- 0 <= size <= 65,535 --> + <!ATTLIST window + size %Digits; #REQUIRED> + + <!-- + checksum as in ip, but with + the following pseudo-header added into the tcp element: + --> + <!ELEMENT tcp.pseudoheader (source, destination, protocol, + tcp.length)> + + <!-- + tcp header + data length in octets. does not include the size of + + the pseudoheader. + --> + + + +Kennedy Informational [Page 12] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + <!ELEMENT tcp.length EMPTY> + <!ATTLIST tcp.length + value %Digits; #REQUIRED> + + <!ELEMENT urgent EMPTY> + <!-- 0 <= pointer <= 65,535 --> + <!ATTLIST urgent + pointer %Digits; #REQUIRED> + + <!ELEMENT tcp.options (tcp.end | tcp.noop | tcp.mss)+> + + <!ELEMENT tcp.end EMPTY> + <!ATTLIST tcp.end + kind CDATA #FIXED "0"> + + <!ELEMENT tcp.noop EMPTY> + <!ATTLIST tcp.noop + kind CDATA #FIXED "1"> + + <!ELEMENT tcp.mss EMPTY> + <!ATTLIST tcp.mss + kind CDATA #FIXED "2" + length CDATA #FIXED "4" + size %Digits; #REQUIRED> + +7.3. UDPoXML DTD + + <!-- + DTD for UDP over XML. + Refer to this DTD as: + + <!DOCTYPE udp PUBLIC "-//IETF//DTD BLOAT 1.0 UDP//EN" "bloat.dtd"> + --> + + <!ELEMENT udp (udp.pseudoheader?, udp.header, payload)> + + <!ELEMENT udp.header (src, dest, udp.length, checksum)> + + <!ELEMENT udp.pseudoheader (source, destination, protocol, + udp.length)> + + <!-- + udp header + data length in octets. does not include the size of + the pseudoheader. + --> + <!ELEMENT udp.length EMPTY> + <!ATTLIST udp.length + value %Digits; #REQUIRED> + + + +Kennedy Informational [Page 13] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +8. Security Considerations + + XML, as a subset of SGML, has the same security considerations as + specified in SGML Media Types [RFC1874]. Security considerations + that apply to IP, TCP and UDP also likely apply to BLOAT as it does + not attempt to correct for issues not related to message format. + +9. References + + [JABBER] Miller, J., "Jabber", draft-miller-jabber-00.txt, + February 2002. (Work in Progress) + + [RFC768] Postel, J., "User Datagram Protocol", STD 6, RFC 768, + August 1980. + + [RFC791] Postel, J., "Internet Protocol", STD 5, RFC 791, + September 1981. + + [RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC + 793, September 1981. + + [RFC894] Hornig, C., "Standard for the Transmission of IP + Datagrams over Ethernet Networks.", RFC 894, April 1984. + + [RFC1042] Postel, J. and J. Reynolds, "Standard for the + Transmission of IP Datagrams Over IEEE 802 Networks", STD + 43, RFC 1042, February 1988. + + [RFC1123] Braden, R., "Requirements for Internet Hosts - + Application and Support", RFC 1123, October 1989. + + [RFC1874] Levinson, E., "SGML Media Types", RFC 1874, December + 1995. + + [RFC2003] Perkins, C., "IP Encapsulation within IP", RFC 2003, + October 1996. + + [RFC2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail + Extensions (MIME) Part One: Format of Internet Message + Bodies", RFC 2045, November 1996. + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC2279] Yergeau, F., "UTF-8, a transformation format of ISO + 10646", RFC 2279, January 1998. + + + + + +Kennedy Informational [Page 14] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + + [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6 + (IPv6) Specification", RFC 2460, December 1998. + + [RFC3080] Rose, M., "The Blocks Extensible Exchange Protocol Core", + RFC 3080, March 2001. + + [SOAP] Box, D., Ehnebuske, D., Kakivaya, G., Layman, A., + Mendelsohn, N., Nielsen, H. F., Thatte, S. Winer, D., + "Simple Object Access Protocol (SOAP) 1.1" World Wide Web + Consortium Note, May 2000 http://www.w3.org/TR/SOAP/ + + [XML] Bray, T., Paoli, J., Sperberg-McQueen, C. M., "Extensible + Markup Language (XML)" World Wide Web Consortium + Recommendation REC- xml-19980210. + http://www.w3.org/TR/1998/REC-xml-19980210 + +10. Author's Address + + Hugh Kennedy + Mimezine + 1060 West Addison + Chicago, IL 60613 + USA + + EMail: kennedyh@engin.umich.edu + + + + + + + + + + + + + + + + + + + + + + + + + + +Kennedy Informational [Page 15] + +RFC 3252 Binary Lexical Octet Ad-hoc Transport 1 April 2002 + + +11. Full Copyright Statement + + Copyright (C) The Internet Society (2002). All Rights Reserved. + + This document and translations of it may be copied and furnished to + others, and derivative works that comment on or otherwise explain it + or assist in its implementation may be prepared, copied, published + and distributed, in whole or in part, without restriction of any + kind, provided that the above copyright notice and this paragraph are + included on all such copies and derivative works. However, this + document itself may not be modified in any way, such as by removing + the copyright notice or references to the Internet Society or other + Internet organizations, except as needed for the purpose of + developing Internet standards in which case the procedures for + copyrights defined in the Internet Standards process must be + followed, or as required to translate it into languages other than + English. + + The limited permissions granted above are perpetual and will not be + revoked by the Internet Society or its successors or assigns. + + This document and the information contained herein is provided on an + "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING + TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING + BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION + HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +Acknowledgement + + Funding for the RFC Editor function is currently provided by the + Internet Society. + + + + + + + + + + + + + + + + + + + +Kennedy Informational [Page 16] + |