-REST format URIs will generally take the form of:
+REST format URLs will generally take the form of:
/ctdl/objectClass/[container/]object[/operation]
// Dispatcher for paths starting with /ctdl/a/
void ctdl_a(struct http_transaction *h, struct ctdlsession *c) {
- if (!strcasecmp(h->uri, "/ctdl/a/login")) { // log in
+ if (!strcasecmp(h->url, "/ctdl/a/login")) { // log in
try_login(h, c);
return;
}
- if (!strcasecmp(h->uri, "/ctdl/a/logout")) { // log out
+ if (!strcasecmp(h->url, "/ctdl/a/logout")) { // log out
logout(h, c);
return;
}
- if (!strcasecmp(h->uri, "/ctdl/a/whoami")) { // return display name of user
+ if (!strcasecmp(h->url, "/ctdl/a/whoami")) { // return display name of user
whoami(h, c);
return;
}
-Method URI Function
+Method URL Function
------ ------------------------------ -------------------------------------
GET /ctdl/a/landing.html Site root redirects to here
GET /ctdl/r/ returns a JSON-encoded list of accessible rooms
// Dispatcher for paths starting with /ctdl/c/
void ctdl_c(struct http_transaction *h, struct ctdlsession *c) {
- if (!strcasecmp(h->uri, "/ctdl/c/info")) {
+ if (!strcasecmp(h->url, "/ctdl/c/info")) {
serv_info(h, c);
}
else {
while (len = client_readline(ch, buf, sizeof buf), (len > 0)) {
++lines_read;
- if (lines_read == 1) { // First line is method and URI.
+ if (lines_read == 1) { // First line is method and URL.
c = strchr(buf, ' '); // IGnore the HTTP-version.
if (c == NULL) {
h.method = strdup("NULL");
- h.uri = strdup("/");
+ h.url = strdup("/");
}
else {
*c = 0;
*c = 0;
}
++c;
- h.uri = strdup(d);
+ h.url = strdup(d);
}
}
else { // Subsequent lines are headers.
syslog(LOG_DEBUG, "Client disconnected");
}
else {
- syslog(LOG_DEBUG, "\033[33m\033[1m< %s %s\033[0m", h.method, h.uri);
+ syslog(LOG_DEBUG, "\033[33m\033[1m< %s %s\033[0m", h.method, h.url);
// If there is a request body, read it now.
char *ccl = header_val(&h, "Content-Length");
}
if (h.method)
free(h.method);
- if (h.uri)
- free(h.uri);
+ if (h.url)
+ free(h.url);
if (h.request_body)
free(h.request_body);
if (h.response_string)
void perform_request(struct http_transaction *h) {
struct ctdlsession *c;
- // Determine which code path to take based on the beginning of the URI.
+ // Determine which code path to take based on the beginning of the URL.
// This is implemented as a series of strncasecmp() calls rather than a
// lookup table in order to make the code more readable.
- if (IsEmptyStr(h->uri)) { // Sanity check
+ if (IsEmptyStr(h->url)) { // Sanity check
do_404(h);
return;
}
// with the /ctdl/ prefix.
// Root (/) ...
- if ((!strcmp(h->uri, "/")) && (!strcasecmp(h->method, "GET"))) {
+ if ((!strcmp(h->url, "/")) && (!strcasecmp(h->method, "GET"))) {
http_redirect(h, "/ctdl/s/index.html");
return;
}
- // Legacy URI patterns (/readnew?gotoroom=xxx&start_reading_at=yyy) ...
+ // Legacy URL patterns (/readnew?gotoroom=xxx&start_reading_at=yyy) ...
// Direct room name (/my%20blog) ...
- // Everything below this line is strictly REST URI patterns.
+ // Everything below this line is strictly REST URL patterns.
- if (strncasecmp(h->uri, HKEY("/ctdl/"))) { // Reject non-REST
+ if (strncasecmp(h->url, HKEY("/ctdl/"))) { // Reject non-REST
do_404(h);
return;
}
- if (!strncasecmp(h->uri, HKEY("/ctdl/s/"))) { // Static content
+ if (!strncasecmp(h->url, HKEY("/ctdl/s/"))) { // Static content
output_static(h);
return;
}
- if (h->uri[7] != '/') {
+ if (h->url[7] != '/') {
do_404(h);
return;
}
}
}
- // Break down the URI by path and send the request to the appropriate part of the program.
- switch (h->uri[6]) {
+ // Break down the URL by path and send the request to the appropriate part of the program.
+ switch (h->url[6]) {
case 'a': // /ctdl/a/ == RESTful path to admin functions
ctdl_a(h, c);
break;
add_response_header(h, strdup("Set-Cookie"), strdup(koekje));
}
- // During development we are foiling the browser cache completely. In production we'll be more selective.
+ // Durlng development we are foiling the browser cache completely. In production we'll be more selective.
add_response_header(h, strdup("Cache-Control"), strdup("no-store, must-revalidate"));
add_response_header(h, strdup("Pragma"), strdup("no-cache"));
add_response_header(h, strdup("Expires"), strdup("0"));
long msgnum = (-1);
char unescaped_euid[1024];
- extract_token(buf, h->uri, 4, '/', sizeof buf);
+ extract_token(buf, h->url, 4, '/', sizeof buf);
if (!strncasecmp(buf, "msgs.", 5)) { // Client is requesting a list of message numbers
unescape_input(&buf[5]);
// A sixth component in the URL can be one of two things:
// (1) a MIME part specifier, in which case the client wants to download that component within the message
// (2) a content-type, in which ase the client wants us to try to render it a certain way
- if (num_tokens(h->uri, '/') == 6) {
- extract_token(buf, h->uri, 5, '/', sizeof buf);
+ if (num_tokens(h->url, '/') == 6) {
+ extract_token(buf, h->url, 5, '/', sizeof buf);
if (!IsEmptyStr(buf)) {
if (!strcasecmp(buf, "json")) {
json_render_one_message(h, c, msgnum);
char buf[1024];
// All room-related functions require being "in" the room specified. Are we in that room already?
- extract_token(requested_roomname, h->uri, 3, '/', sizeof requested_roomname);
+ extract_token(requested_roomname, h->url, 3, '/', sizeof requested_roomname);
unescape_input(requested_roomname);
if (IsEmptyStr(requested_roomname)) { // /ctdl/r/
}
// At this point our Citadel client session is "in" the specified room.
- if (num_tokens(h->uri, '/') == 4) // /ctdl/r/roomname
+ if (num_tokens(h->url, '/') == 4) // /ctdl/r/roomname
{
the_room_itself(h, c);
return;
}
- extract_token(buf, h->uri, 4, '/', sizeof buf);
- if (num_tokens(h->uri, '/') == 5) {
+ extract_token(buf, h->url, 4, '/', sizeof buf);
+ if (num_tokens(h->url, '/') == 5) {
if (IsEmptyStr(buf)) {
the_room_itself(h, c); // /ctdl/r/roomname/ ( same as /ctdl/r/roomname )
}
}
return;
}
- if (num_tokens(h->uri, '/') == 6) {
+ if (num_tokens(h->url, '/') == 6) {
object_in_room(h, c); // /ctdl/r/roomname/object/ or possibly /ctdl/r/roomname/object/component
return;
}
char filename[PATH_MAX];
struct stat statbuf;
- snprintf(filename, sizeof filename, "static/%s", &h->uri[8]);
+ snprintf(filename, sizeof filename, "static/%s", &h->url[8]);
if (strstr(filename, "../")) { // 100% guaranteed attacker.
do_404(h); // Die in a car fire.
void object_in_user(struct http_transaction *h, struct ctdlsession *c, char *requested_username) {
char object_name[1024];
- extract_token(object_name, h->uri, 4, '/', sizeof object_name);
+ extract_token(object_name, h->url, 4, '/', sizeof object_name);
if (!strcasecmp(object_name, "userpic")) { // user photo (avatar)
fetch_user_photo(h, c, requested_username);
char buf[1024];
// All user-related functions require accessing the user in question.
- extract_token(requested_username, h->uri, 3, '/', sizeof requested_username);
+ extract_token(requested_username, h->url, 3, '/', sizeof requested_username);
unescape_input(requested_username);
if (IsEmptyStr(requested_username)) { // /ctdl/u/
// At this point we have extracted the name of the user we're interested in.
// FIXME should we validate it?
- if (num_tokens(h->uri, '/') == 4) { // /ctdl/u/username
+ if (num_tokens(h->url, '/') == 4) { // /ctdl/u/username
the_user_itself(h, c, requested_username);
return;
}
- extract_token(buf, h->uri, 4, '/', sizeof buf);
- if (num_tokens(h->uri, '/') == 5) {
+ extract_token(buf, h->url, 4, '/', sizeof buf);
+ if (num_tokens(h->url, '/') == 5) {
if (IsEmptyStr(buf)) {
the_user_itself(h, c, requested_username); // /ctdl/u/username/ ( same as /ctdl/u/username )
}
return;
}
- if (num_tokens(h->uri, '/') == 6) {
+ if (num_tokens(h->url, '/') == 6) {
object_in_user(h, c, requested_username); // /ctdl/u/username/object/ or possibly /ctdl/u/username/object/component
return;
}
struct http_transaction { // The lifetime of an HTTP request goes through this data structure.
char *method; // The top half is built up by the web server and sent up to the
- char *uri; // application stack. The second half is built up by the application
+ char *url; // application stack. The second half is built up by the application
char *http_version; // stack and sent back down to the web server, which transmits it to
char *site_prefix; // the client.
struct http_header *request_headers;