There are no available options for this view.

Parent Directory Parent Directory | Revision <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Log">Log</a> Revision <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Log">Log</a>

Revision 1.1.1.1 - (show annotations) (download) (as text) (vendor branch)
Mon Mar 10 17:57:37 2003 UTC (9 years, 2 months ago) by rmadilo
Branch: nsreturnz, MAIN
CVS Tags: initial, HEAD
Changes since 1.1: +0 -0 lines
File MIME type: text/x-chdr
Initial nsreturnz import
1 /*
2 * The contents of this file are subject to the AOLserver Public License
3 * Version 1.1 (the "License"); you may not use this file except in
4 * compliance with the License. You may obtain a copy of the License at
5 * http://aolserver.com/.
6 *
7 * Software distributed under the License is distributed on an "AS IS"
8 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9 * the License for the specific language governing rights and limitations
10 * under the License.
11 *
12 * The Original Code is AOLserver Code and related documentation
13 * distributed by AOL.
14 *
15 * The Initial Developer of the Original Code is America Online,
16 * Inc. Portions created by AOL are Copyright (C) 1999 America Online,
17 * Inc. All Rights Reserved.
18 *
19 * Alternatively, the contents of this file may be used under the terms
20 * of the GNU General Public License (the "GPL"), in which case the
21 * provisions of GPL are applicable instead of those above. If you wish
22 * to allow use of your version of this file only under the terms of the
23 * GPL and not to allow others to use your version of this file under the
24 * License, indicate your decision by deleting the provisions above and
25 * replace them with the notice and other provisions required by the GPL.
26 * If you do not delete the provisions above, a recipient may use your
27 * version of this file under either the License or the GPL.
28 */
29
30 /*
31 * nsreturnz.c
32 *
33 * AOLserver gzip compression module.
34 */
35
36
37 static const char *RCSID = "@(#) $Header: /cvsroot-fuse/aolserver/nsreturnz/nsreturnz.c,v 1.1.1.1 2003/03/10 17:57:37 rmadilo Exp $, compiled: " __DATE__ " " __TIME__;
38
39
40 #include "ns.h"
41
42 /*
43 * This code adds a new TCL command named "ns_returnz" to AOLserver.
44 * To test this module, add the following to the
45 * [ns\server\server-name\modules] section of your nsd.ini file:
46 * rubylane.so on Unix platforms
47 *
48 * You can then run your "ns_returnz" command from the /NS/EvalTcl
49 * interface provided by AOLserver.
50 */
51
52 DllExport int Ns_ModuleVersion = 1;
53 static Tcl_CmdProc <a href="/cvs/aolserver/nsreturnz/nsreturnz.c#A_NsreturnzCmd">NsreturnzCmd</a>;
54
55 #define GZIP_FILE_HEADER \
56 "\037\213" /* GZIP magic number */ \
57 "\010" /* Z_DEFLATED */ \
58 "\000" /* flags */ \
59 "\000\000\000\000" /* timestamp */ \
60 "\000" /* xflags */ \
61 "\003" /* Unix OS_CODE */
62
63 static int
64 <a href="/cvs/aolserver/nsreturnz/nsreturnz.c#A_NsreturnzCmd">NsreturnzCmd</a>(ClientData buf, Tcl_Interp *interp, int argc, char **argv)
65 {
66 int len, do_gzip, rc, outlen, crc;
67 unsigned char *accept, *agent, *outbuf;
68 Ns_Conn *conn;
69 Ns_Set *headers;
70
71 if (argc < 4) {
72 Tcl_AppendResult(interp, "wrong # args: should be \"",
73 argv[0], " status mime string\"", NULL);
74 return TCL_ERROR;
75 }
76
77 /* get connection structure */
78 conn = <a href="/cvs/aolserver/aolserver/nsd/tclinit.c#A_Ns_TclGetConn">Ns_TclGetConn</a>(interp);
79 if (conn == NULL) {
80 Tcl_AppendResult(interp, "NULL conn??", NULL);
81 return TCL_ERROR;
82 }
83
84 /* get headers, see if browser supports compression */
85 do_gzip = 0;
86 headers = <a href="/cvs/aolserver/aolserver/nsd/conn.c#A_Ns_ConnHeaders">Ns_ConnHeaders</a>(conn);
87 if (headers != NULL) {
88 accept = <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetIGet">Ns_SetIGet</a>(headers, "Accept-Encoding");
89 agent = <a href="/cvs/aolserver/aolserver/nsd/set.c#A_Ns_SetIGet">Ns_SetIGet</a>(headers, "User-Agent");
90 if (accept != NULL && strstr(accept, "gzip") != NULL && (agent == NULL || strstr(agent, "MSIE 5.0; Mac") == NULL)) {
91 do_gzip = 1;
92 }
93 }
94
95 len = strlen(argv[3]);
96 if (!do_gzip) {
97 <a href="/cvs/aolserver/aolserver/nsd/return.c#A_Ns_ConnReturnData">Ns_ConnReturnData</a>(conn, atoi(argv[1]), argv[3], len, argv[2]);
98 return TCL_OK;
99 }
100
101 /* going to gzip! Man says:
102
103 "Compresses the source buffer into the destination buffer. The level
104 parameter has the same meaning as in deflateInit. sourceLen is the
105 byte length of the source buffer. Upon entry, destLen is the total
106 size of the destination buffer, which must be at least 0.1% larger
107 than sourceLen plus 12 bytes. Upon exit, destLen is the actual size of
108 the compressed buffer.
109
110 In my tests, level 3 compression is almost twice as fast as level 4,
111 so I picked that. In tests with a 330K HTML file, the result is
112 21K - 27K for levels 1-9, so I picked 3 for speed. (No difference
113 in timing tests between levels 1/2/3 for this data.)
114
115 To make a gzip file, 10 bytes are added at the beginning, the
116 first 2 and last 4 bytes of compress2 result are ignored (dunno why),
117 and a CRC of the orig string and len of orig string are added in
118 little-endian byte order. Messy, messy...
119
120 */
121
122 outlen = len*1.002+12+sizeof(GZIP_FILE_HEADER)+8;
123 outbuf = Ns_Malloc(outlen); /* AOLServer crashes if this fails */
124 outlen = outlen-16; /* don't let compress2 use the whole thing */
125 rc = compress2(outbuf+8, &outlen, argv[3], len, 3);
126 #define Z_OK 0
127 if (rc != Z_OK) {
128 Ns_Free(outbuf);
129 <a href="/cvs/aolserver/aolserver/nsd/log.c#A_Ns_Log">Ns_Log</a>(Notice, "ns_returnz: compress2 failed, status=%d", rc);
130 <a href="/cvs/aolserver/aolserver/nsd/return.c#A_Ns_ConnReturnData">Ns_ConnReturnData</a>(conn, atoi(argv[1]), argv[3], len, argv[2]);
131 return TCL_OK;
132 }
133
134 <a href="/cvs/aolserver/aolserver/nsd/return.c#A_Ns_ConnSetHeaders">Ns_ConnSetHeaders</a>(conn, "Content-Encoding", "gzip");
135 #define Z_NULL 0
136 crc = crc32(0, Z_NULL, 0);
137 crc = crc32(crc, argv[3], len);
138
139 /* copy the gzip header into the first 10 bytes, wiping out the
140 first 2 bytes from compress2. Add 8 to outlen for the gzip
141 header (10-2), subtract 4 because we're ignoring the last 4
142 bytes of compress2 */
143
144 memcpy(outbuf, GZIP_FILE_HEADER, 10);
145 outlen = outlen+10-2-4;
146
147 /* append the crc and length, 4 bytes each in LE order */
148
149 *(unsigned char *)(outbuf+outlen+0) = (crc & 0x000000ff);
150 *(unsigned char *)(outbuf+outlen+1) = (crc & 0x0000ff00) >> 8;
151 *(unsigned char *)(outbuf+outlen+2) = (crc & 0x00ff0000) >> 16;
152 *(unsigned char *)(outbuf+outlen+3) = (crc & 0xff000000) >> 24;
153
154 *(unsigned char *)(outbuf+outlen+4) = (len & 0x000000ff);
155 *(unsigned char *)(outbuf+outlen+5) = (len & 0x0000ff00) >> 8;
156 *(unsigned char *)(outbuf+outlen+6) = (len & 0x00ff0000) >> 16;
157 *(unsigned char *)(outbuf+outlen+7) = (len & 0xff000000) >> 24;
158
159 outlen += 8;
160
161 <a href="/cvs/aolserver/aolserver/nsd/return.c#A_Ns_ConnReturnData">Ns_ConnReturnData</a>(conn, atoi(argv[1]), outbuf, outlen, argv[2]);
162 Ns_Free(outbuf);
163 return TCL_OK;
164
165 }
166
167 static int
168 <a href="/cvs/aolserver/nsreturnz/nsreturnz.c#A_NsreturnzInterpInit">NsreturnzInterpInit</a>(Tcl_Interp *interp, void *context)
169 {
170 Tcl_CreateCommand(interp, "ns_returnz", <a href="/cvs/aolserver/nsreturnz/nsreturnz.c#A_NsreturnzCmd">NsreturnzCmd</a>, NULL, NULL);
171 return NS_OK;
172 }
173
174 DllExport int
175 Ns_ModuleInit(char *hServer, char *hModule)
176 {
177 return (<a href="/cvs/aolserver/aolserver/nsd/tclinit.c#A_Ns_TclInitInterps">Ns_TclInitInterps</a>(hServer, <a href="/cvs/aolserver/nsreturnz/nsreturnz.c#A_NsreturnzInterpInit">NsreturnzInterpInit</a>, NULL));
178 }
179
180