1 /** @file
2
3 A brief file description
4
5 @section license License
6
7 Licensed to the Apache Software Foundation (ASF) under one
8 or more contributor license agreements. See the NOTICE file
9 distributed with this work for additional information
10 regarding copyright ownership. The ASF licenses this file
11 to you under the Apache License, Version 2.0 (the
12 "License"); you may not use this file except in compliance
13 with the License. You may obtain a copy of the License at
14
15 http://www.apache.org/licenses/LICENSE-2.0
16
17 Unless required by applicable law or agreed to in writing, software
18 distributed under the License is distributed on an "AS IS" BASIS,
19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 See the License for the specific language governing permissions and
21 limitations under the License.
22 */
23
24 /*
25 * server_push.c:
26 * an example of server push.
27 *
28 *
29 * Usage:
30 * server_push.so http://example.com/favicon.ico
31 *
32 *
33 */
34 #include <stdio.h>
35 #include <string.h>
36 #include <ctype.h>
37
38 #include "ts/ts.h"
39 #include "tscore/ink_defs.h"
40
41 const char *PLUGIN_NAME = "server_push";
42
43 char url[256];
44
45 bool
should_push(TSHttpTxn txnp)46 should_push(TSHttpTxn txnp)
47 {
48 TSMBuffer mbuf;
49 TSMLoc hdr, in_url;
50 if (TSHttpTxnClientReqGet(txnp, &mbuf, &hdr) != TS_SUCCESS) {
51 return false;
52 }
53 if (TSHttpHdrUrlGet(mbuf, hdr, &in_url) != TS_SUCCESS) {
54 return false;
55 }
56 int len;
57 TSUrlHttpQueryGet(mbuf, in_url, &len);
58 TSHandleMLocRelease(mbuf, hdr, in_url);
59 TSHandleMLocRelease(mbuf, TS_NULL_MLOC, hdr);
60 if (len > 0) {
61 return true;
62 } else {
63 return false;
64 }
65 }
66
67 static int
server_push_plugin(TSCont contp,TSEvent event,void * edata)68 server_push_plugin(TSCont contp, TSEvent event, void *edata)
69 {
70 TSHttpSsn ssnp;
71 TSHttpTxn txnp;
72
73 switch (event) {
74 case TS_EVENT_HTTP_SSN_START:
75 ssnp = (TSHttpSsn)edata;
76 TSHttpSsnHookAdd(ssnp, TS_HTTP_TXN_START_HOOK, contp);
77 TSHttpSsnReenable(ssnp, TS_EVENT_HTTP_CONTINUE);
78 break;
79 case TS_EVENT_HTTP_TXN_START:
80 txnp = (TSHttpTxn)edata;
81 TSHttpTxnHookAdd(txnp, TS_HTTP_READ_REQUEST_HDR_HOOK, contp);
82 TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
83 break;
84 case TS_EVENT_HTTP_READ_REQUEST_HDR:
85 txnp = (TSHttpTxn)edata;
86 if (should_push(txnp)) {
87 TSHttpTxnServerPush(txnp, url, strlen(url));
88 }
89 TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
90 break;
91 default:
92 break;
93 }
94
95 return 0;
96 }
97
98 void
TSPluginInit(int argc ATS_UNUSED,const char * argv[]ATS_UNUSED)99 TSPluginInit(int argc ATS_UNUSED, const char *argv[] ATS_UNUSED)
100 {
101 TSPluginRegistrationInfo info;
102
103 info.plugin_name = PLUGIN_NAME;
104 info.vendor_name = "Apache Software Foundation";
105 info.support_email = "dev@trafficserver.apache.org";
106
107 if (TSPluginRegister(&info) != TS_SUCCESS) {
108 TSError("[%s] Plugin registration failed", PLUGIN_NAME);
109 }
110
111 TSstrlcpy(url, argv[1], sizeof(url));
112 TSCont handler = TSContCreate(server_push_plugin, NULL);
113 TSHttpHookAdd(TS_HTTP_SSN_START_HOOK, handler);
114 }
115