Example #1
0
/*
 * Send back a simple error page
 */
void
http_response_send_error(struct http_response *resp,
	int code, const char *fmt, ...)
{
	struct http_request *const req = resp->msg->conn->req;
	const char *ua;
	FILE *fp;
	int i;

	/* Check headers already sent */
	if (resp->msg->hdrs_sent)
		return;

	/* Set response line info */
	http_response_set_header(resp, 0, HDR_REPLY_STATUS, "%d", code);
	http_response_set_header(resp, 0, HDR_REPLY_REASON,
	      "%s", http_response_status_msg(code));

	/* Set additional headers */
	http_response_set_header(resp, 0, HTTP_HEADER_CONTENT_TYPE,
		"text/html; charset=iso-8859-1");

	/* Close connection for real errors */
	if (code >= 400) {
		http_response_set_header(resp,
		    0, _http_message_connection_header(resp->msg), "close");
	}

	/* Send error page body */
	if ((fp = http_response_get_output(resp, 1)) == NULL)
		return;
	fprintf(fp, "<HTML>\n<HEAD>\n<TITLE>%d %s</TITLE></HEAD>\n",
	    code, http_response_status_msg(code));
	fprintf(fp, "<BODY BGCOLOR=\"#FFFFFF\">\n<H3>%d %s</H3>\n",
	    code, http_response_status_msg(code));
	if (fmt != NULL) {
		va_list args;

		fprintf(fp, "<B>");
		va_start(args, fmt);
		vfprintf(fp, fmt, args);
		va_end(args);
		fprintf(fp, "</B>\n");
	}
#if 0
	fprintf(fp, "<P></P>\n<HR>\n");
	fprintf(fp, "<FONT SIZE=\"-1\"><EM>%s</EM></FONT>\n",
	    serv->server_name);
#endif

	/* Add fillter for IE */
	if ((ua = http_request_get_header(req, HTTP_HEADER_USER_AGENT)) != NULL
	    && strstr(ua, "IE") != NULL) {
		for (i = 0; i < 20; i++) {
			fprintf(fp, "<!-- FILLER TO MAKE INTERNET EXPLORER SHOW"
			    " THIS PAGE INSTEAD OF ITS OWN PAGE -->\n");
		}
	}
	fprintf(fp, "</BODY>\n</HTML>\n");
}
Example #2
0
/*
 * Send an HTTP redirect.
 */
void
http_response_send_redirect(struct http_response *resp, const char *url)
{
	const char *name;
	const char *value;

	while (_http_head_get_by_index(resp->msg->head, 0, &name, &value) == 0)
		_http_head_remove(resp->msg->head, name);
	http_response_set_header(resp, 0, HDR_REPLY_STATUS,
	      "%d", HTTP_STATUS_MOVED_PERMANENTLY);
	http_response_set_header(resp, 0, HDR_REPLY_REASON,
	      "%s", http_response_status_msg(HTTP_STATUS_MOVED_PERMANENTLY));
	http_response_set_header(resp, 0, "Location", "%s", url);
}
/*
 * Send a copy of the message, wait for a reply, and return the reply.
 *
 * The "reply" should already be initialized.
 *
 * This properly handles the calling thread's being canceled.
 */
int
http_xml_send(struct http_client *client, struct in_addr ip,
	u_int16_t port, int https, const char *urlpath, const char *username,
	const char *password, const char *ptag, const char *pattrs,
	const struct structs_type *ptype, const void *payload, int pflags,
	const char *rtag, char **rattrsp, const char *rattrs_mtype,
	const struct structs_type *rtype, void *reply, int rflags,
	structs_xmllog_t *rlogger)
{
	struct http_client_connection *cc;
	struct http_request *req;
	struct http_response *resp;
	int ret = -1;
	u_int code;
	FILE *fp;

	/* Get HTTP connection */
	if ((cc = http_client_connect(client, ip, port, https)) == NULL) {
		alogf(LOG_ERR, "can't %s for %s:%u: %m",
		    "get HTTP client" _ inet_ntoa(ip) _ port);
		return -1;
	}

	/* Push cleanup hook */
	pthread_cleanup_push(http_xml_send_cleanup, cc);

	/* Set up request */
	req = http_client_get_request(cc);
	if (http_request_set_method(req,
	    payload != NULL ? HTTP_METHOD_POST : HTTP_METHOD_GET) == -1) {
		alogf(LOG_ERR, "can't %s for %s:%u: %m",
		    "set method" _ inet_ntoa(ip) _ port);
		goto fail;
	}
	if (http_request_set_path(req, urlpath) == -1) {
		alogf(LOG_ERR, "can't %s for %s:%u: %m",
		    "set path" _ inet_ntoa(ip) _ port);
		goto fail;
	}
	if (http_request_set_header(req, 0, "Content-Type", "text/xml") == -1) {
		alogf(LOG_ERR, "can't %s for %s:%u: %m",
		    "set content-type" _ inet_ntoa(ip) _ port);
		goto fail;
	}
	if (username != NULL && password != NULL) {
		char *auth;

		if ((auth = http_request_encode_basic_auth(TYPED_MEM_TEMP,
		    username, password)) == NULL) {
			alogf(LOG_ERR, "can't %s for %s:%u: %m",
			    "encode authorization" _ inet_ntoa(ip) _ port);
			goto fail;
		}
		if (http_request_set_header(req, 0, "Authorization",
		    "Basic %s", auth) == -1) {
			alogf(LOG_ERR, "can't %s for %s:%u: %m",
			    "set authorization header" _ inet_ntoa(ip) _ port);
			FREE(TYPED_MEM_TEMP, auth);
			goto fail;
		}
		FREE(TYPED_MEM_TEMP, auth);
	}

	/* Write XML data to HTTP client output stream */
	if (payload != NULL) {
		if ((fp = http_request_get_output(req, 1)) == NULL) {
			alogf(LOG_ERR, "can't %s for %s:%u: %m",
			    "get output" _ inet_ntoa(ip) _ port);
			goto fail;
		}
		if (structs_xml_output(ptype,
		    ptag, pattrs, payload, fp, NULL, pflags) == -1) {
			alogf(LOG_ERR, "can't %s for %s:%u: %m",
			    "write XML" _ inet_ntoa(ip) _ port);
			goto fail;
		}
	}

	/* Get response */
	if ((resp = http_client_get_response(cc)) == NULL) {
		alogf(LOG_ERR, "can't %s for %s:%u: %m",
		    "get response" _ inet_ntoa(ip) _ port);
		goto fail;
	}
	if ((code = http_response_get_code(resp)) != HTTP_STATUS_OK) {
		alogf(LOG_ERR, "rec'd HTTP error code %d from"
		      "http%s://%s:%u%s: %s", code _ https ? "s" : "" _
		      inet_ntoa(ip) _ port _ urlpath _
		      http_response_status_msg(code));
		goto fail;
	}

	/* Read XML reply from client input stream */
	if ((fp = http_response_get_input(resp)) == NULL) {
		alogf(LOG_ERR, "can't %s for %s:%u: %m",
		    "get input" _ inet_ntoa(ip) _ port);
		goto fail;
	}
	if (structs_xml_input(rtype, rtag, rattrsp,
	    rattrs_mtype, fp, reply, rflags, rlogger) == -1) {
		alogf(LOG_ERR, "can't %s for %s:%u: %m",
		    "read XML reply" _ inet_ntoa(ip) _ port);
		goto fail;
	}

	/* OK */
	ret = 0;

fail:;
	/* Done */
	pthread_cleanup_pop(1);
	return (ret);
}