рдкреЛрд╕реНрдЯ рд╕реА рдореЗрдВ рд▓рд┐рдЦреА рдЧрдИ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдореЗрдВ
рдПрдХреНрд╕рдПрдордПрд▓-рдЖрд░рдкреАрд╕реА рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЛ рдПрдореНрдмреЗрдб рдХрд░рдиреЗ рдХреЗ рдореЗрд░реЗ рдЕрдиреБрднрд╡ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдЧрд╛ред рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХреЗ рдЖрдВрдХрдбрд╝реЛрдВ рдФрд░ рдкрд░рд┐рдгрд╛рдореЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рдкреНрд░рджрд╛рди рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред рдпрд╛рддрд╛рдпрд╛рдд рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ
gzip рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдУрдВ рдХрд╛ рд╕рдорд░реНрдерди рд╣реИред рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдЦреВрди рдХреЗ рд╕рд╛рде рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдФрд░ рдпрд╣ рд╡рд╣реА рд╣реИ рдЬреЛ рдпрд╣ рдЖрдпрд╛ рдерд╛ред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдкрд░реАрдХреНрд╖рдг
рдЖрдЗрдП рдкрд░реАрдХреНрд╖рдгреЛрдВ рд╕реЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдЕрдЬрдЧрд░ рдПрдХреНрд╕рдПрдордПрд▓-рдЖрд░рдкреАрд╕реА рдХреНрд▓рд╛рдЗрдВрдЯ 4 рд▓рд╛рдЗрдиреЛрдВ рдореЗрдВ рдлрд┐рдЯ рдмреИрдарддрд╛ рд╣реИред рд╡реИрд╕реЗ, рд╡рд╣ рд╕рд┐рд░реНрдл gzip рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдЙрддреНрддрд░ рд╕рдордЭрддрд╛ рд╣реИред
import xmlrpclib if __name__ == '__main__': proxy = xmlrpclib.ServerProxy("http://localhost:8080/", verbose=True) print proxy.sayHello()
рдмрд╣реБрдд рдмрдврд╝рд┐рдпрд╛! рдЕрдм рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ HTTP рд╣реЗрдбрд░ рдХреНрдпрд╛ рдорд┐рд▓рддрд╛ рд╣реИред рдФрд░ рдЕрдЧрд░ рдкреНрд░рд╛рд░реВрдк рдЧрд▓рдд рд╣реИ - рд╣рдореЗрдВ рдПрдХ рд╡рд┐рд╕реНрддреГрдд рдХреЙрд▓ рд╕реНрдЯреИрдХ рдХреЗ рд╕рд╛рде рдПрдХ рдЕрдкрд╡рд╛рдж рдорд┐рд▓рддрд╛ рд╣реИред рддреНрд░реБрдЯрд┐ рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдпрд╣ рд╕рдм рд╣рдореЗрдВ рдЗрд╕рдХреА рдШрдЯрдирд╛ рдХреЗ рдХрд╛рд░рдг рдкрд░ рдкреНрд░рдХрд╛рд╢ рдбрд╛рд▓рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред
zlib
рд╡рд┐рдХреА рдХрд╛ рдХрд╣рдирд╛ рд╣реИ рдХрд┐ рдЧрдЬрд╝рд┐рдк рдкреНрд░рд╛рд░реВрдк
рдбрд┐рдлреНрд▓реЗрдЯ рдХрдореНрдкреНрд░реЗрд╢рди рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ, рдЬрд┐рд╕реЗ
рдЬрд╝рд╛рд▓рд┐рдм рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛
рд╣реИ ред рдЗрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдПрдХ рдмреЗрд╣рддрд░реАрди рдХрдВрдкреНрд░реЗрд╕ рд╡рд┐рдзрд┐ рд╣реИред
int compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
рдЦреЛрдЬ рдкрд░ рдЦреБрд╢реА рдЬрддрд╛рддреЗ рд╣реБрдП, рдореИрдВрдиреЗ рддреБрд░рдВрдд рдЗрд╕ рддрд░реАрдХреЗ рдХреЛ рдЖрдЬрдорд╛рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдФрд░ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдлреНрд░реЗрдорд╡рд░реНрдХ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рдерд╛ред рдХреНрд▓рд╛рдЗрдВрдЯ рдиреЗ рд╕рд░реНрд╡рд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рд╕рдордЭрдиреЗ рд╕реЗ рдЗрдирдХрд╛рд░ рдХрд░ рджрд┐рдпрд╛ рдФрд░ рдПрдХ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде рдмрд╛рд╣рд░ рдЧрд┐рд░ рдЧрдпрд╛ред рдореБрдЭреЗ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдЧрдЬрд╝рд┐рдк рдкреНрд░рд╛рд░реВрдк рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рдирд╛ рдерд╛ред
gzip
рдпрд╣рд╛рдБ рд╕рдм рдХреБрдЫ рдмрд╣реБрдд
рд╕рд░рд▓ рд╣реИ ред

рд╕рдВрдкреАрдбрд╝рд┐рдд рдбреЗрдЯрд╛ рдХреЛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рд╛рд░реВрдк рд╣реЗрдбрд░ рдХреЗ рджрд╕ рдмрд╛рдЗрдЯреНрд╕ рдФрд░ рдПрдХ рдкреНрд░рддреНрдпрдп рдХреЗ рдЖрда рдмрд╛рдЗрдЯреНрд╕ рд╕реНрд░реЛрдд рдбреЗрдЯрд╛ рдФрд░ рдЗрд╕рдХреА рд▓рдВрдмрд╛рдИ рдХреЗ рдЪреЗрдХрд╕рдо рд╕реЗ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рд╣реЗрдбрд░ рдореИрдЬрд┐рдХ рдХреЙрдиреНрд╕реНрдЯреЗрдВрдЯ
ID1 = 31 (0x1f, \ 037),
ID2 = 139 (0x8b, \ 213) рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, gzip рдлреЙрд░реНрдореЗрдЯ рдореЗрдВ рдбреЗрдЯрд╛ рдХреА рд╢реБрд░реБрдЖрдд рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддрд╛ рд╣реИред рдЕрдЧрд▓рд╛ рд╕рдВрдкреАрдбрд╝рди рд╡рд┐рдзрд┐ (
рд╕реАрдПрдо ) рд╣реИ, рд╕реАрдПрдо = 8 рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВред рдЭрдВрдбреЗ рдХреЗ рдмрд╛рдж рд╡реНрдпрд╕реНрдд, рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ
FLG = 1, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдкрд╛рда рдбреЗрдЯрд╛ред рдлрд┐рд░ рд╕реНрд░реЛрдд рдбреЗрдЯрд╛ рдореЗрдВ рдЕрдВрддрд┐рдо рдкрд░рд┐рд╡рд░реНрддрди рдХреА рддрд╛рд░реАрдЦ рдХреЗ 4 рдмрд╛рдЗрдЯреНрд╕ рд╣реИрдВ, рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ
MTIME = 0ред рдлрд┐рд░ рдЕрддрд┐рд░рд┐рдХреНрдд рдЭрдВрдбреЗ
XFL = 2 (рдЙрдЪреНрдЪ рд╕рдВрдкреАрдбрд╝рди рдЕрдиреБрдкрд╛рдд) рд╣реИрдВред рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдирд╛рдо рд╣рдореЗрдВ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд
рдУрдПрд╕ = 255 рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИред
рдЪреЗрдХрд╕рдо рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЙрд╕реА zlib рд╕реЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ
uLong crc32 (uLong crc, const Bytef *buf, uInt len);
рд▓реЗрдХрд┐рди рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИред рд╣рдорд╛рд░рд╛ рдЧреНрд░рд╛рд╣рдХ рдЕрднреА рднреА рд╕рд░реНрд╡рд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдУрдВ рд╕реЗ рдЦреБрд╢ рдирд╣реАрдВ рд╣реИред
рдЬрд╝рд╛рд▓рд┐рдм рдлрд┐рд░ рд╕реЗ
рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ zlib рдбреЗрдЯрд╛ рд╣рдореЗрдВ рдХрд┐рд╕ рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рд▓реМрдЯрд╛рддрд╛ рд╣реИред

рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ zlib рд╕рдВрдкреАрдбрд╝рд┐рдд рдбреЗрдЯрд╛ (
рдЕрдзрд┐рдХ ) рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖ 2-рдмрд╛рдЗрдЯ рдЙрдкрд╕рд░реНрдЧ рдФрд░ 4-рдмрд╛рдЗрдЯ рдкреНрд░рддреНрдпрдп рдЬреЛрдбрд╝рддрд╛ рд╣реИред рдЙрдирд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдПрдВ рдФрд░ рдЧрдЬрд╝рд┐рдк рд╣реЗрдбрд░ рдФрд░ рдкреНрд░рддреНрдпрдп рдЬреЛрдбрд╝реЗрдВред
рдФрд░ рд▓реЛ! рдЧреНрд░рд╛рд╣рдХ рдЖрдЦрд┐рд░рдХрд╛рд░ рд╣рдореЗрдВ рд╕рдордЭ рдЧрдпрд╛!
рдиреЛрдЯ: Qt рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдПрдХ qCompress () рд╡рд┐рдзрд┐ рд╣реИ рдЬреЛ рдбреЗрдЯрд╛ рдХреЛ zlib рд▓рд╛рдЗрдмреНрд░реЗрд░реА рджреНрд╡рд╛рд░рд╛ рд╕рдВрдкреАрдбрд╝рд┐рдд рдХрд░рддреА рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд╛рде рд╣реА рд╕рдВрдкреАрдбрд╝рд┐рдд рдбреЗрдЯрд╛ рдХреА рд▓рдВрдмрд╛рдИ рдХреЗ рд▓рд┐рдП 4-рдмрд╛рдЗрдЯ рдЙрдкрд╕рд░реНрдЧ рдХреЗ рд╕рд╛рдередрдкрд░рд┐рдгрд╛рдо
рдЧрдЬрд╝рд┐рдк рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдбреЗрдЯрд╛ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕реНрд░реЛрдд рдбреЗрдЯрд╛ рдХреЛ
рд╕реЗрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде
рд╕рдВрдкреАрдбрд╝рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд╕рд░рдгреА рдореЗрдВ рд╣рдо рдкрд╣рд▓реЗ 2 рдмрд╛рдЗрдЯреНрд╕ рдХреЛ 10-рдмрд╛рдЗрдЯ рдЧрдЬрд╝рд┐рдк рд╣реИрдбрд░ рдХреЗ рд╕рд╛рде рдмрджрд▓рддреЗ рд╣реИрдВ, рдкрд┐рдЫрд▓реЗ 4 рдмрд╛рдЗрдЯреНрд╕ рдХреЗ рдмрдЬрд╛рдп рд╣рдо рдЪреЗрдХрд╕рдо рдФрд░ рдореВрд▓ рдбреЗрдЯрд╛ рдХреА рд▓рдВрдмрд╛рдИ рдбрд╛рд▓рддреЗ рд╣реИрдВред
рдПрдХ рдХрд╛рд░реНрдпрд╢реАрд▓ XML-RPC рд╕рд░реНрд╡рд░ рдХрд╛ рдЙрджрд╛рд╣рд░рдг рдЬреЛ gzip рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдбреЗрдЯрд╛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
#include <zlib.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <netinet/in.h> #include <sys/socket.h> #define PORT 8080 #define MAXCONN 5 #define BUF_SZ 1024 #define ZLIB_PREFIX_SZ 2 #define ZLIB_SUFFIX_SZ 4 #define GZIP_PREFIX_SZ 10 #define GZIP_SUFFIX_SZ 8 // Returns listen socket handle int create_srvsock(int port, int maxconn); // Returns response to be sent back int get_response(int clisock, char *response); // Writes given data range to socket void write_range(int sock, const char *begin, const char *end); // Write int value to socket void write_int(int sock, int value); // Prints error message and exit void error(const char *msg); int main(int argc, const char *argv[]) { fprintf(stderr, "HTTP Server with gzip encoding support using zlib (%s)\r\n", ZLIB_VERSION); char httpheaders[BUF_SZ] = {0,}; char response[BUF_SZ] = {0,}; char compressed[BUF_SZ] = {0,}; int srvsock = create_srvsock(PORT, MAXCONN); fprintf(stderr, "Server is started on port %d\r\n", PORT); while (true) { struct sockaddr_in addr = {0,}; socklen_t addrlen = sizeof(addr); // 1. Accepting connection int clisock = accept(srvsock, (struct sockaddr *)&addr, &addrlen); // 2. Retreiving response int responselen = get_response(clisock, response); // 3. Compressing response long unsigned int compressedlen = BUF_SZ; if (compress((unsigned char *)compressed, &compressedlen , (const unsigned char *)response, responselen) != Z_OK) error("Can not compress"); // substract zlib prefix and suffix: http://www.ietf.org/rfc/rfc1950.txt compressedlen -= ZLIB_PREFIX_SZ + ZLIB_SUFFIX_SZ; // 4. Writing HTTP headers int contentlen = GZIP_PREFIX_SZ + compressedlen + GZIP_SUFFIX_SZ; int httpheaderslen = sprintf(httpheaders, "HTTP/1.1 200 OK\r\n"\ "Content-Type: text/xml\r\n"\ "Content-Encoding: gzip\r\n"\ "Content-Length: %d\r\n\r\n", contentlen); write_range(clisock, httpheaders, httpheaders + httpheaderslen); // 5. Writing gzip headers: http://www.gzip.org/zlib/rfc-gzip.html const char gzipheader[] = { 0x1f, 0x8b // gzip magic number , 8 // compress method "defalte" , 1 // text data , 0, 0, 0, 0 // timestamp is not set , 2 // maximum compression flag , 255 // unknown OS }; write_range(clisock, gzipheader, gzipheader + sizeof(gzipheader)); // 6. Write compressed data write_range(clisock, compressed + ZLIB_PREFIX_SZ , compressed + ZLIB_PREFIX_SZ + compressedlen); // 7. Append crc32 write_int(clisock, (int)crc32(0, (unsigned char *)response, responselen)); // 8. Append initial size write_int(clisock, responselen); } return EXIT_SUCCESS; } // Returns listen socket handle int create_srvsock(int port, int maxconn) { int sock = 0; struct sockaddr_in addr = {0,}; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = INADDR_ANY; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) error("Can not open socket"); if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) error("Can not bind socket"); if (listen(sock, maxconn) < 0) error("Can not listen socket"); return sock; } // Returns response to be sent back int get_response(int clisock, char *response) { return sprintf(response, "<?xml version=\"1.0\"?>\r\n"\ "<methodResponse>\r\n"\ " <params><param><value>Hello there!</value></param></params>\r\n"\ "</methodResponse>"); } // Writes given data range to socket void write_range(int sock, const char* begin, const char *end) { for (const char *it = begin; it != end;) { int written = write(sock, it, end - it); if (written < 0) error("Can not write to socket"); it += written; } } // Write int value to socket void write_int(int sock, int value) { const char *data = (const char *)&value; write_range(sock, data, data + sizeof(int)); } // Prints error message and exit void error(const char *msg) { perror(msg); exit(EXIT_FAILURE); }