2 * Copyright (C) 2007 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include <atompub/atom.h>
24 #define _GNU_SOURCE /* for asprintf */
32 uri_is_absolute (char *uri)
41 char *request_uri = getenv ("REQUEST_URI");
42 char *path = getenv ("PATH_INFO");
43 char *host = getenv ("HTTP_HOST");
44 char *server = getenv ("SERVER_NAME");
45 char *sport = getenv ("SERVER_PORT");
49 port = strtol (sport, NULL, 0);
55 if (request_uri == NULL)
57 if (uri_is_absolute (request_uri))
59 uri = strdup (request_uri);
63 asprintf (&uri, "http://%s%s", host, request_uri);
65 else if (server && port != 0 && port != 80)
67 asprintf (&uri, "http://%s:%d%s", server, port, request_uri);
71 asprintf (&uri, "http://%s%s", server, request_uri);
75 size_t pathl = strlen (path);
76 size_t uril = strlen (uri);
77 if (!strncmp (uri + uril - pathl, path, pathl))
79 *(uri + uril - pathl) = 0;
91 origslug = getenv ("HTTP_SLUG");
94 slug = strdup (origslug);
95 for (s = slug; *s; s++)
102 cgi_request_content_set (AtomCtx *ctx, AtomRequest *request)
105 GError *error = NULL;
108 channel = g_io_channel_unix_new (0);
109 if (g_io_channel_read_to_end (channel, &data, &len, &error) !=
112 AtomError *aerr = atom_error_new_from_gerror (error);
113 g_io_channel_unref (channel);
114 atom_error_set (ctx, aerr);
115 g_error_free (error);
118 atom_request_content_set (request, data, len);
119 g_io_channel_unref (channel);
124 cgi_get_request (AtomCtx *ctx)
127 char *method = getenv ("REQUEST_METHOD");
128 char *path = getenv ("PATH_INFO");
129 AtomRequest *request;
132 error = atom_error_new ();
133 atom_error_code_set (error, 400);
134 atom_error_message_set (error, "Bad Request");
135 atom_error_set (ctx, error);
138 if (path == NULL || *path == '\0')
140 if (!strcmp (method, "POST"))
142 error = atom_error_new ();
143 atom_error_code_set (error, 400);
144 atom_error_message_set (error, "Bad Request");
145 atom_error_set (ctx, error);
150 if (!strcmp (method, "GET"))
152 /* Remove the leading slash before mapping */
153 return atom_request_new (ATOM_REQUEST_GET, path + 1);
155 else if (!strcmp (method, "POST"))
157 char *slug = getslug ();
162 reqname = strdup (path + 1);
163 request = atom_request_new (ATOM_REQUEST_POST, reqname);
165 cgi_request_content_set (ctx, request);
166 if (atom_error_get (ctx) != NULL)
168 atom_request_delete (request);
173 error = atom_error_new ();
174 atom_error_code_set (error, 501);
175 atom_error_message_set (error, "Not Implemented");
176 atom_error_set (ctx, error);
181 cgi_handle_error (AtomCtx *ctx)
184 if ((error = atom_error_get (ctx)) != NULL)
186 int code = atom_error_code (error);
187 char *message = atom_error_message (error);
188 fprintf (stdout, "Status: %d %s\n\n%s\n", code, message, message);
192 fprintf (stdout, "Status: 500 Server error\n\nServer error\n");
197 cgi_write_header (void)
200 header = "Content-type: application/atom+xml\n\n";
201 write (1, header, strlen (header));
205 cgi_handle_entry (AtomCtx *ctx, AtomEntry *entry)
210 atom_entry_string (entry, &str, &len);
211 atom_entry_delete (entry);
217 cgi_handle_feed (AtomCtx *ctx, AtomFeed *feed)
222 atom_feed_string (feed, &str, &len);
223 atom_feed_delete (feed);
229 cgi_handle_publish (AtomCtx *ctx, AtomEntry *entry)
234 req = atom_id_to_backend (ctx, atom_entry_id (entry));
235 fprintf (stdout, "Status: 201 Created\n");
236 fprintf (stdout, "Location: %s%s\n", getbaseurl (), req);
238 atom_entry_string (entry, &str, &len);
239 atom_entry_delete (entry);
245 cgi_is_feed (AtomCtx *ctx, char *req)
247 return (req == NULL || *req == '\0');
253 AtomFrontend *frontend;
254 frontend = atom_frontend_new ();
255 atom_frontend_map_entries_set (frontend, atom_map_frontend_requests);
256 atom_frontend_is_feed_set (frontend, cgi_is_feed);
257 atom_frontend_get_request_set (frontend, cgi_get_request);
258 atom_frontend_handle_error_set (frontend, cgi_handle_error);
259 atom_frontend_handle_entry_set (frontend, cgi_handle_entry);
260 atom_frontend_handle_feed_set (frontend, cgi_handle_feed);
261 atom_frontend_handle_publish_set (frontend, cgi_handle_publish);