xref: /trafficserver/iocore/cache/CacheHttp.cc (revision 4cfd5a73)
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 #include "tscore/ink_config.h"
25 #include <cstring>
26 #include "P_Cache.h"
27 
28 /*-------------------------------------------------------------------------
29   -------------------------------------------------------------------------*/
30 
31 static vec_info default_vec_info;
32 
33 static CacheHTTPInfo default_http_info;
34 
CacheHTTPInfoVector()35 CacheHTTPInfoVector::CacheHTTPInfoVector() : data(&default_vec_info, 4) {}
36 
37 /*-------------------------------------------------------------------------
38   -------------------------------------------------------------------------*/
39 
~CacheHTTPInfoVector()40 CacheHTTPInfoVector::~CacheHTTPInfoVector()
41 {
42   int i;
43 
44   for (i = 0; i < xcount; i++) {
45     data[i].alternate.destroy();
46   }
47   vector_buf.clear();
48   magic = nullptr;
49 }
50 
51 /*-------------------------------------------------------------------------
52   -------------------------------------------------------------------------*/
53 
54 int
insert(CacheHTTPInfo * info,int index)55 CacheHTTPInfoVector::insert(CacheHTTPInfo *info, int index)
56 {
57   if (index == CACHE_ALT_INDEX_DEFAULT) {
58     index = xcount++;
59   }
60 
61   data(index).alternate.copy_shallow(info);
62   return index;
63 }
64 
65 /*-------------------------------------------------------------------------
66   -------------------------------------------------------------------------*/
67 
68 void
detach(int idx,CacheHTTPInfo * r)69 CacheHTTPInfoVector::detach(int idx, CacheHTTPInfo *r)
70 {
71   int i;
72 
73   ink_assert(idx >= 0);
74   ink_assert(idx < xcount);
75 
76   r->copy_shallow(&data[idx].alternate);
77   data[idx].alternate.destroy();
78 
79   for (i = idx; i < (xcount - 1); i++) {
80     data[i] = data[i + i];
81   }
82 
83   xcount -= 1;
84 }
85 
86 /*-------------------------------------------------------------------------
87   -------------------------------------------------------------------------*/
88 
89 void
remove(int idx,bool destroy)90 CacheHTTPInfoVector::remove(int idx, bool destroy)
91 {
92   if (destroy) {
93     data[idx].alternate.destroy();
94   }
95 
96   for (; idx < (xcount - 1); idx++) {
97     data[idx] = data[idx + 1];
98   }
99 
100   xcount--;
101 }
102 
103 /*-------------------------------------------------------------------------
104   -------------------------------------------------------------------------*/
105 
106 void
clear(bool destroy)107 CacheHTTPInfoVector::clear(bool destroy)
108 {
109   int i;
110 
111   if (destroy) {
112     for (i = 0; i < xcount; i++) {
113       data[i].alternate.destroy();
114     }
115   }
116   xcount = 0;
117   data.clear();
118   vector_buf.clear();
119 }
120 
121 /*-------------------------------------------------------------------------
122   -------------------------------------------------------------------------*/
123 
124 void
print(char * buffer,size_t buf_size,bool temps)125 CacheHTTPInfoVector::print(char *buffer, size_t buf_size, bool temps)
126 {
127   char buf[CRYPTO_HEX_SIZE], *p;
128   int purl;
129   int i, tmp;
130 
131   p    = buffer;
132   purl = 1;
133 
134   for (i = 0; i < xcount; i++) {
135     if (data[i].alternate.valid()) {
136       if (purl) {
137         Arena arena;
138         char *url;
139 
140         purl = 0;
141         URL u;
142         data[i].alternate.request_url_get(&u);
143         url = u.string_get(&arena);
144         if (url) {
145           snprintf(p, buf_size, "[%s] ", url);
146           tmp = strlen(p);
147           p += tmp;
148           buf_size -= tmp;
149         }
150       }
151 
152       if (temps || !(data[i].alternate.object_key_get() == zero_key)) {
153         snprintf(p, buf_size, "[%d %s]", data[i].alternate.id_get(), CacheKey(data[i].alternate.object_key_get()).toHexStr(buf));
154         tmp = strlen(p);
155         p += tmp;
156         buf_size -= tmp;
157       }
158     }
159   }
160 }
161 
162 /*-------------------------------------------------------------------------
163   -------------------------------------------------------------------------*/
164 
165 int
marshal_length()166 CacheHTTPInfoVector::marshal_length()
167 {
168   int length = 0;
169 
170   for (int i = 0; i < xcount; i++) {
171     length += data[i].alternate.marshal_length();
172   }
173 
174   return length;
175 }
176 
177 /*-------------------------------------------------------------------------
178   -------------------------------------------------------------------------*/
179 int
marshal(char * buf,int length)180 CacheHTTPInfoVector::marshal(char *buf, int length)
181 {
182   char *start = buf;
183   int count   = 0;
184 
185   ink_assert(!(((intptr_t)buf) & 3)); // buf must be aligned
186 
187   for (int i = 0; i < xcount; i++) {
188     int tmp = data[i].alternate.marshal(buf, length);
189     length -= tmp;
190     buf += tmp;
191     count++;
192   }
193 
194   GLOBAL_CACHE_SUM_GLOBAL_DYN_STAT(cache_hdr_vector_marshal_stat, 1);
195   GLOBAL_CACHE_SUM_GLOBAL_DYN_STAT(cache_hdr_marshal_stat, count);
196   GLOBAL_CACHE_SUM_GLOBAL_DYN_STAT(cache_hdr_marshal_bytes_stat, buf - start);
197   return buf - start;
198 }
199 
200 int
unmarshal(const char * buf,int length,RefCountObj * block_ptr)201 CacheHTTPInfoVector::unmarshal(const char *buf, int length, RefCountObj *block_ptr)
202 {
203   ink_assert(!(((intptr_t)buf) & 3)); // buf must be aligned
204 
205   const char *start = buf;
206   CacheHTTPInfo info;
207   xcount = 0;
208 
209   while (length - (buf - start) > static_cast<int>(sizeof(HTTPCacheAlt))) {
210     int tmp = HTTPInfo::unmarshal(const_cast<char *>(buf), length - (buf - start), block_ptr);
211     if (tmp < 0) {
212       return -1;
213     }
214     info.m_alt = (HTTPCacheAlt *)buf;
215     buf += tmp;
216 
217     data(xcount).alternate = info;
218     xcount++;
219   }
220 
221   return (const_cast<caddr_t>(buf) - const_cast<caddr_t>(start));
222 }
223 
224 /*-------------------------------------------------------------------------
225   -------------------------------------------------------------------------*/
226 uint32_t
get_handles(const char * buf,int length,RefCountObj * block_ptr)227 CacheHTTPInfoVector::get_handles(const char *buf, int length, RefCountObj *block_ptr)
228 {
229   ink_assert(!(((intptr_t)buf) & 3)); // buf must be aligned
230 
231   const char *start = buf;
232   CacheHTTPInfo info;
233   xcount = 0;
234 
235   vector_buf = block_ptr;
236 
237   while (length - (buf - start) > static_cast<int>(sizeof(HTTPCacheAlt))) {
238     int tmp = info.get_handle(const_cast<char *>(buf), length - (buf - start));
239     if (tmp < 0) {
240       ink_assert(!"CacheHTTPInfoVector::unmarshal get_handle() failed");
241       return static_cast<uint32_t>(-1);
242     }
243     buf += tmp;
244 
245     data(xcount).alternate = info;
246     xcount++;
247   }
248 
249   return (const_cast<caddr_t>(buf) - const_cast<caddr_t>(start));
250 }
251