3eee2582d74aad2925119b15294da56274224e40
[shibboleth/cpp-xmltooling.git] / xmltooling / io / HTTPResponse.cpp
1 /*
2  *  Copyright 2009 Internet2
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * HTTPResponse.cpp
19  * 
20  * Interface to HTTP responses.
21  */
22
23 #include "internal.h"
24 #include "HTTPResponse.h"
25
26 using namespace xmltooling;
27 using namespace std;
28
29 GenericResponse::GenericResponse()
30 {
31 }
32
33 GenericResponse::~GenericResponse()
34 {
35 }
36
37 vector<string> HTTPResponse::m_allowedSchemes;
38
39 vector<string>& HTTPResponse::getAllowedSchemes()
40 {
41     return m_allowedSchemes;
42 }
43
44 void HTTPResponse::sanitizeURL(const char* url)
45 {
46     const char* ch;
47     for (ch=url; *ch; ++ch) {
48         if (iscntrl((unsigned char)(*ch)))  // convert to unsigned to allow full range from 00-FF
49             throw IOException("URL contained a control character.");
50     }
51
52     ch = strchr(url, ':');
53     if (!ch)
54         throw IOException("URL is malformed.");
55     string s(url, ch - url);
56     for (vector<string>::const_iterator i = m_allowedSchemes.begin(); i != m_allowedSchemes.end(); ++i) {
57 #ifdef HAVE_STRCASECMP
58         if (!strcasecmp(s.c_str(), i->c_str()))
59 #else
60         if (!stricmp(s.c_str(), i->c_str()))
61 #endif
62             return;
63     }
64
65     throw IOException("URL contains invalid scheme ($1).", params(1, s.c_str()));
66 }
67
68 HTTPResponse::HTTPResponse()
69 {
70 }
71
72 HTTPResponse::~HTTPResponse()
73 {
74 }
75
76 void HTTPResponse::setContentType(const char* type)
77 {
78     setResponseHeader("Content-Type", type);
79 }
80
81 void HTTPResponse::setCookie(const char* name, const char* value)
82 {
83     string cookie(name);
84     cookie = cookie + '=' + value;
85     setResponseHeader("Set-Cookie", cookie.c_str());
86 }
87
88 void HTTPResponse::setResponseHeader(const char* name, const char* value)
89 {
90     for (const char* ch=name; *ch; ++ch) {
91         if (iscntrl(*ch))
92             throw IOException("Response header name contained a control character.");
93     }
94
95     for (const char* ch=value; *ch; ++ch) {
96         if (iscntrl(*ch))
97             throw IOException("Value for response header ($1) contained a control character.", params(1,name));
98     }
99 }
100
101 long HTTPResponse::sendRedirect(const char* url)
102 {
103     sanitizeURL(url);
104     return XMLTOOLING_HTTP_STATUS_MOVED;
105 }
106
107 long HTTPResponse::sendError(istream& inputStream)
108 {
109     return sendResponse(inputStream, XMLTOOLING_HTTP_STATUS_ERROR);
110 }
111
112 long HTTPResponse::sendResponse(istream& inputStream)
113 {
114     return sendResponse(inputStream, XMLTOOLING_HTTP_STATUS_OK);
115 }