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