summaryrefslogtreecommitdiffabout
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
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 (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,176 +1,181 @@
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);