summaryrefslogtreecommitdiffabout
path: root/ui-shared.c
authorEric Wong <normalperson@yhbt.net>2008-09-01 06:30:33 (UTC)
committer Lars Hjemli <hjemli@gmail.com>2008-09-01 23:26:37 (UTC)
commit9c931b1e6e68f8dc891a5653035c3d70038ae3c0 (patch) (unidiff)
treea5cd6d953eb66ad77eb4e5b088e2022973fc4f61 /ui-shared.c
parent687fb6d833d25144c86d1841fe0eca611f1eaeb1 (diff)
downloadcgit-9c931b1e6e68f8dc891a5653035c3d70038ae3c0.zip
cgit-9c931b1e6e68f8dc891a5653035c3d70038ae3c0.tar.gz
cgit-9c931b1e6e68f8dc891a5653035c3d70038ae3c0.tar.bz2
use Host: header to generate cgit_hosturl
I run an instance of lighttpd for cgit behind nginx (nginx doesn't execute CGI). So the port (SERVER_PORT=33333) that lighttpd runs on sends to cgit is different from the standard port 80 that public clients connect to (via nginx). This was causing the Atom feed URL to show the private port number that lighttpd was running on. Since the HTTP/1.1 "Host" header includes the port number if running on a non-standard port, it allows non-client-facing HTTP servers to transparently generate public URLs that clients can see. So use the "Host" header if it is available and fall back to SERVER_NAME/SERVER_PORT for some clients that don't set HTTP_HOST. Signed-off-by: Eric Wong <normalperson@yhbt.net>
Diffstat (limited to 'ui-shared.c') (more/less context) (ignore whitespace changes)
-rw-r--r--ui-shared.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/ui-shared.c b/ui-shared.c
index 4818e70..c23bc75 100644
--- a/ui-shared.c
+++ b/ui-shared.c
@@ -1,304 +1,309 @@
1/* ui-shared.c: common web output functions 1/* ui-shared.c: common web output functions
2 * 2 *
3 * Copyright (C) 2006 Lars Hjemli 3 * Copyright (C) 2006 Lars Hjemli
4 * 4 *
5 * Licensed under GNU General Public License v2 5 * Licensed under GNU General Public License v2
6 * (see COPYING for full license text) 6 * (see COPYING for full license text)
7 */ 7 */
8 8
9#include "cgit.h" 9#include "cgit.h"
10#include "cmd.h" 10#include "cmd.h"
11#include "html.h" 11#include "html.h"
12 12
13const char cgit_doctype[] = 13const char cgit_doctype[] =
14"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n" 14"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n"
15" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"; 15" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
16 16
17static char *http_date(time_t t) 17static char *http_date(time_t t)
18{ 18{
19 static char day[][4] = 19 static char day[][4] =
20 {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; 20 {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
21 static char month[][4] = 21 static char month[][4] =
22 {"Jan", "Feb", "Mar", "Apr", "May", "Jun", 22 {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
23 "Jul", "Aug", "Sep", "Oct", "Now", "Dec"}; 23 "Jul", "Aug", "Sep", "Oct", "Now", "Dec"};
24 struct tm *tm = gmtime(&t); 24 struct tm *tm = gmtime(&t);
25 return fmt("%s, %02d %s %04d %02d:%02d:%02d GMT", day[tm->tm_wday], 25 return fmt("%s, %02d %s %04d %02d:%02d:%02d GMT", day[tm->tm_wday],
26 tm->tm_mday, month[tm->tm_mon], 1900+tm->tm_year, 26 tm->tm_mday, month[tm->tm_mon], 1900+tm->tm_year,
27 tm->tm_hour, tm->tm_min, tm->tm_sec); 27 tm->tm_hour, tm->tm_min, tm->tm_sec);
28} 28}
29 29
30void cgit_print_error(char *msg) 30void cgit_print_error(char *msg)
31{ 31{
32 html("<div class='error'>"); 32 html("<div class='error'>");
33 html_txt(msg); 33 html_txt(msg);
34 html("</div>\n"); 34 html("</div>\n");
35} 35}
36 36
37char *cgit_hosturl() 37char *cgit_hosturl()
38{ 38{
39 char *host, *port; 39 char *host, *port;
40 40
41 host = getenv("SERVER_NAME"); 41 host = getenv("HTTP_HOST");
42 if (!host) 42 if (host) {
43 return NULL;
44 port = getenv("SERVER_PORT");
45 if (port && atoi(port) != 80)
46 host = xstrdup(fmt("%s:%d", host, atoi(port)));
47 else
48 host = xstrdup(host); 43 host = xstrdup(host);
44 } else {
45 host = getenv("SERVER_NAME");
46 if (!host)
47 return NULL;
48 port = getenv("SERVER_PORT");
49 if (port && atoi(port) != 80)
50 host = xstrdup(fmt("%s:%d", host, atoi(port)));
51 else
52 host = xstrdup(host);
53 }
49 return host; 54 return host;
50} 55}
51 56
52char *cgit_rooturl() 57char *cgit_rooturl()
53{ 58{
54 if (ctx.cfg.virtual_root) 59 if (ctx.cfg.virtual_root)
55 return fmt("%s/", ctx.cfg.virtual_root); 60 return fmt("%s/", ctx.cfg.virtual_root);
56 else 61 else
57 return ctx.cfg.script_name; 62 return ctx.cfg.script_name;
58} 63}
59 64
60char *cgit_repourl(const char *reponame) 65char *cgit_repourl(const char *reponame)
61{ 66{
62 if (ctx.cfg.virtual_root) { 67 if (ctx.cfg.virtual_root) {
63 return fmt("%s/%s/", ctx.cfg.virtual_root, reponame); 68 return fmt("%s/%s/", ctx.cfg.virtual_root, reponame);
64 } else { 69 } else {
65 return fmt("?r=%s", reponame); 70 return fmt("?r=%s", reponame);
66 } 71 }
67} 72}
68 73
69char *cgit_fileurl(const char *reponame, const char *pagename, 74char *cgit_fileurl(const char *reponame, const char *pagename,
70 const char *filename, const char *query) 75 const char *filename, const char *query)
71{ 76{
72 char *tmp; 77 char *tmp;
73 char *delim; 78 char *delim;
74 79
75 if (ctx.cfg.virtual_root) { 80 if (ctx.cfg.virtual_root) {
76 tmp = fmt("%s/%s/%s/%s", ctx.cfg.virtual_root, reponame, 81 tmp = fmt("%s/%s/%s/%s", ctx.cfg.virtual_root, reponame,
77 pagename, (filename ? filename:"")); 82 pagename, (filename ? filename:""));
78 delim = "?"; 83 delim = "?";
79 } else { 84 } else {
80 tmp = fmt("?url=%s/%s/%s", reponame, pagename, 85 tmp = fmt("?url=%s/%s/%s", reponame, pagename,
81 (filename ? filename : "")); 86 (filename ? filename : ""));
82 delim = "&"; 87 delim = "&";
83 } 88 }
84 if (query) 89 if (query)
85 tmp = fmt("%s%s%s", tmp, delim, query); 90 tmp = fmt("%s%s%s", tmp, delim, query);
86 return tmp; 91 return tmp;
87} 92}
88 93
89char *cgit_pageurl(const char *reponame, const char *pagename, 94char *cgit_pageurl(const char *reponame, const char *pagename,
90 const char *query) 95 const char *query)
91{ 96{
92 return cgit_fileurl(reponame,pagename,0,query); 97 return cgit_fileurl(reponame,pagename,0,query);
93} 98}
94 99
95const char *cgit_repobasename(const char *reponame) 100const char *cgit_repobasename(const char *reponame)
96{ 101{
97 /* I assume we don't need to store more than one repo basename */ 102 /* I assume we don't need to store more than one repo basename */
98 static char rvbuf[1024]; 103 static char rvbuf[1024];
99 int p; 104 int p;
100 const char *rv; 105 const char *rv;
101 strncpy(rvbuf,reponame,sizeof(rvbuf)); 106 strncpy(rvbuf,reponame,sizeof(rvbuf));
102 if(rvbuf[sizeof(rvbuf)-1]) 107 if(rvbuf[sizeof(rvbuf)-1])
103 die("cgit_repobasename: truncated repository name '%s'", reponame); 108 die("cgit_repobasename: truncated repository name '%s'", reponame);
104 p = strlen(rvbuf)-1; 109 p = strlen(rvbuf)-1;
105 /* strip trailing slashes */ 110 /* strip trailing slashes */
106 while(p && rvbuf[p]=='/') rvbuf[p--]=0; 111 while(p && rvbuf[p]=='/') rvbuf[p--]=0;
107 /* strip trailing .git */ 112 /* strip trailing .git */
108 if(p>=3 && !strncmp(&rvbuf[p-3],".git",4)) { 113 if(p>=3 && !strncmp(&rvbuf[p-3],".git",4)) {
109 p -= 3; rvbuf[p--] = 0; 114 p -= 3; rvbuf[p--] = 0;
110 } 115 }
111 /* strip more trailing slashes if any */ 116 /* strip more trailing slashes if any */
112 while( p && rvbuf[p]=='/') rvbuf[p--]=0; 117 while( p && rvbuf[p]=='/') rvbuf[p--]=0;
113 /* find last slash in the remaining string */ 118 /* find last slash in the remaining string */
114 rv = strrchr(rvbuf,'/'); 119 rv = strrchr(rvbuf,'/');
115 if(rv) 120 if(rv)
116 return ++rv; 121 return ++rv;
117 return rvbuf; 122 return rvbuf;
118} 123}
119 124
120char *cgit_currurl() 125char *cgit_currurl()
121{ 126{
122 if (!ctx.cfg.virtual_root) 127 if (!ctx.cfg.virtual_root)
123 return ctx.cfg.script_name; 128 return ctx.cfg.script_name;
124 else if (ctx.qry.page) 129 else if (ctx.qry.page)
125 return fmt("%s/%s/%s/", ctx.cfg.virtual_root, ctx.qry.repo, ctx.qry.page); 130 return fmt("%s/%s/%s/", ctx.cfg.virtual_root, ctx.qry.repo, ctx.qry.page);
126 else if (ctx.qry.repo) 131 else if (ctx.qry.repo)
127 return fmt("%s/%s/", ctx.cfg.virtual_root, ctx.qry.repo); 132 return fmt("%s/%s/", ctx.cfg.virtual_root, ctx.qry.repo);
128 else 133 else
129 return fmt("%s/", ctx.cfg.virtual_root); 134 return fmt("%s/", ctx.cfg.virtual_root);
130} 135}
131 136
132static void site_url(char *page, char *search, int ofs) 137static void site_url(char *page, char *search, int ofs)
133{ 138{
134 char *delim = "?"; 139 char *delim = "?";
135 140
136 if (ctx.cfg.virtual_root) { 141 if (ctx.cfg.virtual_root) {
137 html_attr(ctx.cfg.virtual_root); 142 html_attr(ctx.cfg.virtual_root);
138 if (ctx.cfg.virtual_root[strlen(ctx.cfg.virtual_root) - 1] != '/') 143 if (ctx.cfg.virtual_root[strlen(ctx.cfg.virtual_root) - 1] != '/')
139 html("/"); 144 html("/");
140 } else 145 } else
141 html(ctx.cfg.script_name); 146 html(ctx.cfg.script_name);
142 147
143 if (page) { 148 if (page) {
144 htmlf("?p=%s", page); 149 htmlf("?p=%s", page);
145 delim = "&"; 150 delim = "&";
146 } 151 }
147 if (search) { 152 if (search) {
148 html(delim); 153 html(delim);
149 html("q="); 154 html("q=");
150 html_attr(search); 155 html_attr(search);
151 delim = "&"; 156 delim = "&";
152 } 157 }
153 if (ofs) { 158 if (ofs) {
154 html(delim); 159 html(delim);
155 htmlf("ofs=%d", ofs); 160 htmlf("ofs=%d", ofs);
156 } 161 }
157} 162}
158 163
159static void site_link(char *page, char *name, char *title, char *class, 164static void site_link(char *page, char *name, char *title, char *class,
160 char *search, int ofs) 165 char *search, int ofs)
161{ 166{
162 html("<a"); 167 html("<a");
163 if (title) { 168 if (title) {
164 html(" title='"); 169 html(" title='");
165 html_attr(title); 170 html_attr(title);
166 html("'"); 171 html("'");
167 } 172 }
168 if (class) { 173 if (class) {
169 html(" class='"); 174 html(" class='");
170 html_attr(class); 175 html_attr(class);
171 html("'"); 176 html("'");
172 } 177 }
173 html(" href='"); 178 html(" href='");
174 site_url(page, search, ofs); 179 site_url(page, search, ofs);
175 html("'>"); 180 html("'>");
176 html_txt(name); 181 html_txt(name);
177 html("</a>"); 182 html("</a>");
178} 183}
179 184
180void cgit_index_link(char *name, char *title, char *class, char *pattern, 185void cgit_index_link(char *name, char *title, char *class, char *pattern,
181 int ofs) 186 int ofs)
182{ 187{
183 site_link(NULL, name, title, class, pattern, ofs); 188 site_link(NULL, name, title, class, pattern, ofs);
184} 189}
185 190
186static char *repolink(char *title, char *class, char *page, char *head, 191static char *repolink(char *title, char *class, char *page, char *head,
187 char *path) 192 char *path)
188{ 193{
189 char *delim = "?"; 194 char *delim = "?";
190 195
191 html("<a"); 196 html("<a");
192 if (title) { 197 if (title) {
193 html(" title='"); 198 html(" title='");
194 html_attr(title); 199 html_attr(title);
195 html("'"); 200 html("'");
196 } 201 }
197 if (class) { 202 if (class) {
198 html(" class='"); 203 html(" class='");
199 html_attr(class); 204 html_attr(class);
200 html("'"); 205 html("'");
201 } 206 }
202 html(" href='"); 207 html(" href='");
203 if (ctx.cfg.virtual_root) { 208 if (ctx.cfg.virtual_root) {
204 html_attr(ctx.cfg.virtual_root); 209 html_attr(ctx.cfg.virtual_root);
205 if (ctx.cfg.virtual_root[strlen(ctx.cfg.virtual_root) - 1] != '/') 210 if (ctx.cfg.virtual_root[strlen(ctx.cfg.virtual_root) - 1] != '/')
206 html("/"); 211 html("/");
207 html_attr(ctx.repo->url); 212 html_attr(ctx.repo->url);
208 if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/') 213 if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
209 html("/"); 214 html("/");
210 if (page) { 215 if (page) {
211 html(page); 216 html(page);
212 html("/"); 217 html("/");
213 if (path) 218 if (path)
214 html_attr(path); 219 html_attr(path);
215 } 220 }
216 } else { 221 } else {
217 html(ctx.cfg.script_name); 222 html(ctx.cfg.script_name);
218 html("?url="); 223 html("?url=");
219 html_attr(ctx.repo->url); 224 html_attr(ctx.repo->url);
220 if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/') 225 if (ctx.repo->url[strlen(ctx.repo->url) - 1] != '/')
221 html("/"); 226 html("/");
222 if (page) { 227 if (page) {
223 html(page); 228 html(page);
224 html("/"); 229 html("/");
225 if (path) 230 if (path)
226 html_attr(path); 231 html_attr(path);
227 } 232 }
228 delim = "&amp;"; 233 delim = "&amp;";
229 } 234 }
230 if (head && strcmp(head, ctx.repo->defbranch)) { 235 if (head && strcmp(head, ctx.repo->defbranch)) {
231 html(delim); 236 html(delim);
232 html("h="); 237 html("h=");
233 html_attr(head); 238 html_attr(head);
234 delim = "&amp;"; 239 delim = "&amp;";
235 } 240 }
236 return fmt("%s", delim); 241 return fmt("%s", delim);
237} 242}
238 243
239static void reporevlink(char *page, char *name, char *title, char *class, 244static void reporevlink(char *page, char *name, char *title, char *class,
240 char *head, char *rev, char *path) 245 char *head, char *rev, char *path)
241{ 246{
242 char *delim; 247 char *delim;
243 248
244 delim = repolink(title, class, page, head, path); 249 delim = repolink(title, class, page, head, path);
245 if (rev && strcmp(rev, ctx.qry.head)) { 250 if (rev && strcmp(rev, ctx.qry.head)) {
246 html(delim); 251 html(delim);
247 html("id="); 252 html("id=");
248 html_attr(rev); 253 html_attr(rev);
249 } 254 }
250 html("'>"); 255 html("'>");
251 html_txt(name); 256 html_txt(name);
252 html("</a>"); 257 html("</a>");
253} 258}
254 259
255void cgit_tree_link(char *name, char *title, char *class, char *head, 260void cgit_tree_link(char *name, char *title, char *class, char *head,
256 char *rev, char *path) 261 char *rev, char *path)
257{ 262{
258 reporevlink("tree", name, title, class, head, rev, path); 263 reporevlink("tree", name, title, class, head, rev, path);
259} 264}
260 265
261void cgit_plain_link(char *name, char *title, char *class, char *head, 266void cgit_plain_link(char *name, char *title, char *class, char *head,
262 char *rev, char *path) 267 char *rev, char *path)
263{ 268{
264 reporevlink("plain", name, title, class, head, rev, path); 269 reporevlink("plain", name, title, class, head, rev, path);
265} 270}
266 271
267void cgit_log_link(char *name, char *title, char *class, char *head, 272void cgit_log_link(char *name, char *title, char *class, char *head,
268 char *rev, char *path, int ofs, char *grep, char *pattern) 273 char *rev, char *path, int ofs, char *grep, char *pattern)
269{ 274{
270 char *delim; 275 char *delim;
271 276
272 delim = repolink(title, class, "log", head, path); 277 delim = repolink(title, class, "log", head, path);
273 if (rev && strcmp(rev, ctx.qry.head)) { 278 if (rev && strcmp(rev, ctx.qry.head)) {
274 html(delim); 279 html(delim);
275 html("id="); 280 html("id=");
276 html_attr(rev); 281 html_attr(rev);
277 delim = "&"; 282 delim = "&";
278 } 283 }
279 if (grep && pattern) { 284 if (grep && pattern) {
280 html(delim); 285 html(delim);
281 html("qt="); 286 html("qt=");
282 html_attr(grep); 287 html_attr(grep);
283 delim = "&"; 288 delim = "&";
284 html(delim); 289 html(delim);
285 html("q="); 290 html("q=");
286 html_attr(pattern); 291 html_attr(pattern);
287 } 292 }
288 if (ofs > 0) { 293 if (ofs > 0) {
289 html(delim); 294 html(delim);
290 html("ofs="); 295 html("ofs=");
291 htmlf("%d", ofs); 296 htmlf("%d", ofs);
292 } 297 }
293 html("'>"); 298 html("'>");
294 html_txt(name); 299 html_txt(name);
295 html("</a>"); 300 html("</a>");
296} 301}
297 302
298void cgit_commit_link(char *name, char *title, char *class, char *head, 303void cgit_commit_link(char *name, char *title, char *class, char *head,
299 char *rev) 304 char *rev)
300{ 305{
301 if (strlen(name) > ctx.cfg.max_msg_len && ctx.cfg.max_msg_len >= 15) { 306 if (strlen(name) > ctx.cfg.max_msg_len && ctx.cfg.max_msg_len >= 15) {
302 name[ctx.cfg.max_msg_len] = '\0'; 307 name[ctx.cfg.max_msg_len] = '\0';
303 name[ctx.cfg.max_msg_len - 1] = '.'; 308 name[ctx.cfg.max_msg_len - 1] = '.';
304 name[ctx.cfg.max_msg_len - 2] = '.'; 309 name[ctx.cfg.max_msg_len - 2] = '.';