/********************************************************************** * * wincgiutils.cpp * Copyright (C) 1996 * * A component of the fnord webserver written by bmorin@wpi.edu. * * Altered for use with the Greenstone digital library software by the * New Zealand Digital Library Project at the University of Waikato, * New Zealand. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *********************************************************************/ #include "text_t.h" #include #include #include "netio.h" #include "httpreq.h" #include "wincgiutils.h" #define default_http_port 80 // Attempt to break a url into segments. If the parsing fails, 'name' is // left pointing to the unparsed portion. int parse_url(const text_t &url, text_t &protocol, text_t &machine, int *port, text_t &name) { protocol.clear(); machine.clear(); *port = default_http_port; name.clear(); text_t::const_iterator begin = url.begin(); text_t::const_iterator end = url.end(); text_t::const_iterator it = findchar(begin, end, ':'); if (it == end) {name = url; return http_error_url_invalid;} if (substr(it+1, it+3) != "//") {name = url; return http_error_url_invalid;} protocol = substr(begin, it); it += 3; while (it < end) { if (*it == ':') { ++it; text_t portstr; while (it != end && (*it >= '0' && *it <= '9')) { portstr.push_back(*it); ++it; } *port = portstr.getint(); if (it == end) break; } if (*it == '/') { while (it != end) { name.push_back(*it); ++it; } break; } machine.push_back(*it); ++it; } return http_ok; } int Send_String(char *str, RequestInfoT *RInfo) { return SendData(RInfo->ClientSocket, (BYTE *)str, strlen(str), RInfo->ThreadNum); } int Send_String_N(char *str, int n, RequestInfoT *RInfo) { return SendData(RInfo->ClientSocket, (BYTE *)str, n, RInfo->ThreadNum); } int send_header(char *content, RequestInfoT *RequestInfo) { char Header[1536]; int len, lenc; //Build Header Header[0] = 0; //Status Line if (content[0] != '@') /*No redirection needed*/ strcat(Header, "HTTP/1.0 200 OK\r\n"); else /*Redirection*/ strcat(Header, "HTTP/1.0 302 Relocation\r\n"); //Server strcat(Header, "Server: GSDL\r\n"); //Content Type strcat(Header, "Content-type: "); if (content[0] != '@') /*No redirection needed*/ strcat(Header, content); else { /*Redirection entry*/ strcat(Header, "text/html \r\n"); strcat(Header, "Location: "); len = strlen(Header); lenc = strlen(content) - 1; strncpy(&Header[len], &content[1], lenc); Header[len+lenc] = 0; } strcat(Header, " \r\n"); //Single CRLF to end header strcat(Header, "\r\n"); return Send_String(Header, RequestInfo); } void send_retrieve_error(int error_num, char *msg1, char *msg2, RequestInfoT *RequestInfo) { char Header[512], Body[512], ErrorNumStr[17], BodyLengthStr[17]; DWORD BodyLength; int HeaderLength; itoa(error_num, ErrorNumStr, 10); //Build Data (so we can determine length for the header) Body[0] = 0; strcat(Body, "Server Error\n"); strcat(Body, "

Error "); strcat(Body, ErrorNumStr); strcat(Body, ": "); strcat(Body, msg1); strcat(Body, "

\n"); strcat(Body, msg2); strcat(Body, "\n"); BodyLength = (DWORD) strlen(Body); //Build Header Header[0] = 0; //Status Line strcat(Header, "HTTP/1.0 "); strcat(Header, ErrorNumStr); strcat(Header, " "); strcat(Header, msg1); strcat(Header, "\r\n"); //Server strcat(Header, "Server: GSDL\r\n"); strcat(Header, "Content-Type: text/html\r\n"); //Content Length itoa(BodyLength, BodyLengthStr, 10); strcat(Header, "Content-Length: "); strcat(Header, BodyLengthStr); strcat(Header, "\r\n"); //Single CRLF to end header strcat(Header, "\r\n"); HeaderLength = strlen(Header); //Send the file if we have one (and if it's not a HEAD request) SendData(RequestInfo->ClientSocket, (BYTE *) Header, strlen(Header), RequestInfo->ThreadNum); // if ((FileFound == FALSE) && (strcmpi(RequestFields.MethodStr, "HEAD") != 0)) { //Send generated data SendData(RequestInfo->ClientSocket, (BYTE *) Body, BodyLength, RequestInfo->ThreadNum); }