Index: trunk/switchboard/fcgi.h |
— | — | @@ -26,6 +26,7 @@ |
27 | 27 | params = 4, |
28 | 28 | stdin_ = 5, |
29 | 29 | stdout_ = 6, |
| 30 | + stderr_ = 7, |
30 | 31 | data = 8, |
31 | 32 | get_values = 9, |
32 | 33 | get_values_result = 10, |
Index: trunk/switchboard/fcgi_response.h |
— | — | @@ -0,0 +1,36 @@ |
| 2 | +/* Copyright (c) 2008 River Tarnell <river@wikimedia.org>. */ |
| 3 | +/* |
| 4 | + * Permission is granted to anyone to use this software for any purpose, |
| 5 | + * including commercial applications, and to alter it and redistribute it |
| 6 | + * freely. This software is provided 'as-is', without any express or implied |
| 7 | + * warranty. |
| 8 | + */ |
| 9 | +/* $Id$ */ |
| 10 | + |
| 11 | +#ifndef FCGI_RESPONSE_H |
| 12 | +#define FCGI_RESPONSE_H |
| 13 | + |
| 14 | +#include <vector> |
| 15 | +#include <string> |
| 16 | + |
| 17 | +#include "fcgi.h" |
| 18 | + |
| 19 | +/* |
| 20 | + * Construct a FastCGI error response. |
| 21 | + */ |
| 22 | + |
| 23 | +struct fcgi_response { |
| 24 | + fcgi_response(int request_id); |
| 25 | + |
| 26 | + void add_stdout(std::string const &text); |
| 27 | + void add_stderr(std::string const &text); |
| 28 | + void end(void); |
| 29 | + |
| 30 | + std::vector<fcgi::record> const &as_vector() const; |
| 31 | + |
| 32 | +private: |
| 33 | + int request_id_; |
| 34 | + std::vector<fcgi::record> records_; |
| 35 | +}; |
| 36 | + |
| 37 | +#endif /* !FCGI_RESPONSE_H */ |
Property changes on: trunk/switchboard/fcgi_response.h |
___________________________________________________________________ |
Added: svn:keywords |
1 | 38 | + Id Revision |
Index: trunk/switchboard/Makefile |
— | — | @@ -34,6 +34,7 @@ |
35 | 35 | config.o \ |
36 | 36 | fcgi_application.o \ |
37 | 37 | fcgi_cgi.o \ |
| 38 | + fcgi_response.o \ |
38 | 39 | fcgi_server_connection.o \ |
39 | 40 | process.o \ |
40 | 41 | process_factory.o \ |
Index: trunk/switchboard/fcgi_application.cc |
— | — | @@ -20,6 +20,7 @@ |
21 | 21 | #include "fcgi_application.h" |
22 | 22 | #include "fcgi_server_connection.h" |
23 | 23 | #include "fcgi_cgi.h" |
| 24 | +#include "fcgi_response.h" |
24 | 25 | |
25 | 26 | using asio::ip::tcp; |
26 | 27 | using boost::format; |
— | — | @@ -71,8 +72,31 @@ |
72 | 73 | } catch (std::exception &e) { |
73 | 74 | LOG4CXX_DEBUG(logger, format( "error creating fcgi_cgi: %s") |
74 | 75 | % e.what()); |
75 | | - if (!server_.expired()) |
| 76 | + if (!server_.expired()) { |
| 77 | + fcgi_response resp(request_id_); |
| 78 | + resp.add_stdout(boost::io::str(boost::format( |
| 79 | +"Status: 500 Internal server error\r\n" |
| 80 | +"Content-Type: text/html;charset=UTF-8\r\n" |
| 81 | +"\r\n" |
| 82 | +"<html><head><title>switchboard error</title></head>\r\n" |
| 83 | +"<body><p>hi,</p>\r\n" |
| 84 | +"<p>i am the PHP switchboard, and i handle PHP requests (like yours) on this server.\r\n" |
| 85 | +"i'm afraid i was unable to handle your request. when i tried, the following\r\n" |
| 86 | +"error occurred: <tt>%1%</tt>.</p>\r\n" |
| 87 | +"<p>please try your request again in a few minutes. if it still doesn't work,\r\n" |
| 88 | +"you should contact the server administrator and inform him of the problem.</p>\r\n" |
| 89 | +"<p>regards,<br> the PHP switchboard.</p>\r\n" |
| 90 | + ) % e.what())); |
| 91 | + resp.end(); |
| 92 | + |
| 93 | + std::vector<fcgi::record> const &recs = resp.as_vector(); |
| 94 | + for (int i = 0; i < recs.size(); ++i) { |
| 95 | + server_.lock()->record_to_server( |
| 96 | + fcgi::recordp(new fcgi::record(recs[i]))); |
| 97 | + } |
| 98 | + |
76 | 99 | server_.lock()->destroy(request_id_); |
| 100 | + } |
77 | 101 | return; |
78 | 102 | } |
79 | 103 | |
Index: trunk/switchboard/fcgi_response.cc |
— | — | @@ -0,0 +1,88 @@ |
| 2 | +/* Copyright (c) 2008 River Tarnell <river@wikimedia.org>. */ |
| 3 | +/* |
| 4 | + * Permission is granted to anyone to use this software for any purpose, |
| 5 | + * including commercial applications, and to alter it and redistribute it |
| 6 | + * freely. This software is provided 'as-is', without any express or implied |
| 7 | + * warranty. |
| 8 | + */ |
| 9 | +/* $Id$ */ |
| 10 | + |
| 11 | +#include "fcgi_response.h" |
| 12 | + |
| 13 | +fcgi_response::fcgi_response(int request_id) |
| 14 | + : request_id_(request_id) |
| 15 | +{ |
| 16 | +} |
| 17 | + |
| 18 | +void |
| 19 | +fcgi_response::add_stdout(std::string const &text) |
| 20 | +{ |
| 21 | + fcgi::record rec; |
| 22 | + std::string::size_type len = text.size(); |
| 23 | + |
| 24 | + rec.contentData.reserve(text.size()); |
| 25 | + std::copy(text.begin(), text.end(), std::back_inserter(rec.contentData)); |
| 26 | + |
| 27 | + rec.version = 1; |
| 28 | + rec.type = fcgi::rectype::stdout_; |
| 29 | + rec.requestId1 = (request_id_ & 0xFF00) >> 8; |
| 30 | + rec.requestId0 = (request_id_ & 0x00FF); |
| 31 | + rec.contentLength1 = (rec.contentData.size() & 0xFF00) >> 8; |
| 32 | + rec.contentLength0 = (rec.contentData.size() & 0x00FF); |
| 33 | + rec.paddingLength = 0; |
| 34 | + rec.reserved = 0; |
| 35 | + |
| 36 | + records_.push_back(rec); |
| 37 | +} |
| 38 | + |
| 39 | +void |
| 40 | +fcgi_response::add_stderr(std::string const &text) |
| 41 | +{ |
| 42 | + fcgi::record rec; |
| 43 | + std::string::size_type len = text.size(); |
| 44 | + |
| 45 | + rec.contentData.reserve(text.size()); |
| 46 | + std::copy(text.begin(), text.end(), std::back_inserter(rec.contentData)); |
| 47 | + |
| 48 | + rec.version = 1; |
| 49 | + rec.type = fcgi::rectype::stderr_; |
| 50 | + rec.requestId1 = (request_id_ & 0xFF00) >> 8; |
| 51 | + rec.requestId0 = (request_id_ & 0x00FF); |
| 52 | + rec.contentLength1 = (rec.contentData.size() & 0xFF00) >> 8; |
| 53 | + rec.contentLength0 = (rec.contentData.size() & 0x00FF); |
| 54 | + rec.paddingLength = 0; |
| 55 | + rec.reserved = 0; |
| 56 | + |
| 57 | + records_.push_back(rec); |
| 58 | +} |
| 59 | + |
| 60 | +void |
| 61 | +fcgi_response::end() |
| 62 | +{ |
| 63 | + fcgi::record rec; |
| 64 | + |
| 65 | + rec.version = 1; |
| 66 | + rec.type = fcgi::rectype::end_request; |
| 67 | + rec.requestId1 = (request_id_ & 0xFF00) >> 8; |
| 68 | + rec.requestId0 = (request_id_ & 0x00FF); |
| 69 | + rec.contentData.push_back(0); |
| 70 | + rec.contentData.push_back(0); |
| 71 | + rec.contentData.push_back(0); |
| 72 | + rec.contentData.push_back(0); |
| 73 | + rec.contentData.push_back(0); |
| 74 | + rec.contentData.push_back(0); |
| 75 | + rec.contentData.push_back(0); |
| 76 | + rec.contentData.push_back(0); |
| 77 | + rec.contentLength1 = (rec.contentData.size() & 0xFF00) >> 8; |
| 78 | + rec.contentLength0 = (rec.contentData.size() & 0x00FF); |
| 79 | + rec.paddingLength = 0; |
| 80 | + rec.reserved = 0; |
| 81 | + |
| 82 | + records_.push_back(rec); |
| 83 | +} |
| 84 | + |
| 85 | +std::vector<fcgi::record> const & |
| 86 | +fcgi_response::as_vector() const |
| 87 | +{ |
| 88 | + return records_; |
| 89 | +} |
Property changes on: trunk/switchboard/fcgi_response.cc |
___________________________________________________________________ |
Added: svn:keywords |
1 | 90 | + Id Revision |
Index: trunk/switchboard/fcgi_cgi.cc |
— | — | @@ -144,7 +144,7 @@ |
145 | 145 | boost::bind(&fcgi_cgi::process_ready, |
146 | 146 | shared_from_this(), func, _1))) |
147 | 147 | { |
148 | | - throw creation_failure("too many queued processes for users"); |
| 148 | + throw creation_failure("too many queued requests for this user"); |
149 | 149 | } |
150 | 150 | } |
151 | 151 | |