Implement new frontend functions for CGI frontend
[cascardo/atompub.git] / frontend / cgi / cgi.c
1 /*
2  *  Copyright (C) 2007  Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
3  *
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.
8  *
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.
13  *
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.
17  */
18
19
20 #include <atompub/atom.h>
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26
27 static AtomRequest *
28 cgi_get_request (AtomCtx *ctx)
29 {
30   AtomError *error;
31   char *method = getenv ("REQUEST_METHOD");
32   char *path = getenv ("PATH_INFO");
33   int type;
34   char *request;
35   if (method == NULL)
36     {
37       error = atom_error_new ();
38       atom_error_code_set (error, 400);
39       atom_error_message_set (error, "Bad Request");
40       atom_error_set (ctx, error);
41       return NULL;
42     }
43   if (path == NULL || *path == '\0')
44     path = "/";
45   if (!strcmp (method, "GET"))
46     {
47       /* Remove the leading slash before mapping */
48       return atom_request_new (ATOM_REQUEST_GET, path + 1);
49     }
50   error = atom_error_new ();
51   atom_error_code_set (error, 501);
52   atom_error_message_set (error, "Not Implemented");
53   atom_error_set (ctx, error);
54   return NULL;
55 }
56
57 static void
58 cgi_handle_error (AtomCtx *ctx)
59 {
60   AtomError *error;
61   if ((error = atom_error_get (ctx)) != NULL)
62     {
63       int code = atom_error_code (error);
64       char *message = atom_error_message (error);
65       fprintf (stdout, "Status: %d %s\n\n%s\n", code, message, message);
66     }
67   else
68     {
69       fprintf (stdout, "Status: 500 Server error\n\nServer error\n");
70     }
71 }
72
73 static void
74 cgi_write_header (void)
75 {
76   char *header;
77   header = "Content-type: application/atom+xml\n\n";
78   write (1, header, strlen (header));
79 }
80
81 static void
82 cgi_handle_entry (AtomCtx *ctx, AtomEntry *entry)
83 {
84   char * str;
85   size_t len;
86   cgi_write_header ();
87   atom_entry_string (entry, &str, &len);
88   atom_entry_delete (entry);
89   write (1, str, len);
90   g_free (str);
91 }
92
93 static void
94 cgi_handle_feed (AtomCtx *ctx, AtomFeed *feed)
95 {
96   char * str;
97   size_t len;
98   cgi_write_header ();
99   atom_feed_string (feed, &str, &len);
100   atom_feed_delete (feed);
101   write (1, str, len);
102   g_free (str);
103 }
104
105 static int
106 cgi_is_feed (AtomCtx *ctx, char *req)
107 {
108   return (req == NULL || *req == '\0');
109 }
110
111 AtomFrontend *
112 cgi_frontend (void)
113 {
114   AtomFrontend *frontend;
115   frontend = atom_frontend_new ();
116   atom_frontend_map_entries_set (frontend, atom_map_frontend_requests);
117   atom_frontend_is_feed_set (frontend, cgi_is_feed);
118   atom_frontend_get_request_set (frontend, cgi_get_request);
119   atom_frontend_handle_error_set (frontend, cgi_handle_error);
120   atom_frontend_handle_entry_set (frontend, cgi_handle_entry);
121   atom_frontend_handle_feed_set (frontend, cgi_handle_feed);
122   return frontend;
123 }