File:  [parser3project] / parser3 / src / include / pa_http.h
Revision 1.37: download - view: text, annotated - select for diffs - revision graph
Sat Apr 25 13:38:46 2026 UTC (5 weeks, 4 days ago) by moko
Branches: MAIN
CVS tags: HEAD
Copyright year updated, websites links changed to https://

/** @file
	Parser: commonly used functions.

	Copyright (c) 2001-2026 Art. Lebedev Studio (https://www.artlebedev.com)
	Authors: Konstantin Morshnev <moko@design.ru>, Alexandr Petrosian <paf@design.ru>
*/

#ifndef PA_HTTP_H
#define PA_HTTP_H

#define IDENT_PA_HTTP_H "$Id: pa_http.h,v 1.37 2026/04/25 13:38:46 moko Exp $"

#include "pa_vstring.h"
#include "pa_vint.h"
#include "pa_vhash.h"
#include "pa_vtable.h"
#include "pa_socks.h"
#include "pa_charset.h"
#include "pa_request.h"

#define HTTP_COOKIES_NAME "cookies"

#ifdef _MSC_VER
#include <windows.h>
#define socklen_t int
#else
#define closesocket close
#define INVALID_SOCKET -1
typedef int SOCKET;
#endif

#ifndef DOXYGEN
struct File_read_http_result {
	char *str; size_t length;
	HashStringValue* headers;
}; 
#endif

class HTTP_Headers {
public:
	class Header {
	public:
		String::Body name;
		String::Body value;

		Header(String::Body aname, String::Body avalue) : name(aname), value(avalue) {}

		void transcode(Charset &charset, Charset &source){
			name=Charset::transcode(name, charset, source);
			value=Charset::transcode(value, charset, source);
		}

	};

	Array<Header> headers;

	String::Body content_type;
	uint64_t content_length;

	HTTP_Headers() : content_type(""), content_length(0){}

	bool add_header(const char *line);

	void clear(){
		headers.clear();
		content_type.clear();
		content_length=0;
	}

};

/*** http part ***/

Table* parse_cookies(Request& r, Table *cookies);
void tables_update(HashStringValue& tables, const String::Body name, const String& value);

char *pa_http_safe_header_name(const char *name);

File_read_http_result pa_internal_file_read_http(Request& r, const String& file_spec, bool as_text, HashStringValue *options=0, bool transcode_text_result=true);

/*** httpd part ***/

//#define HTTPD_DEBUG

class HTTPD_request;

class HTTPD_Connection : public PA_Allocated {
public:
	SOCKET sock;
	const char *remote_addr;
	HTTPD_request *request;

	HTTPD_Connection() : sock(INVALID_SOCKET), remote_addr(NULL), request(NULL){}
	~HTTPD_Connection();

	Array<HTTP_Headers::Header> &headers();

	const char *method();
	const char *uri();
	const char *content_type();
	uint64_t content_length();

	const char *query(){
		if(uri()){
			const char *result=strchr(uri(), '?');
			if(result++ && *result)
				return result;
		}
		return NULL;
	}

	bool accept(SOCKET, int);
	bool read_header();
	size_t read_post(char *, size_t);
	size_t send_body(const void *, size_t);
};

class HTTPD_Server : public PA_Allocated {
public:
	enum HTTPD_MODE {
		SEQUENTIAL,
		PARALLEL,
		MULTITHREADED
	} static mode;
	static const char *port;

	static void set_mode(const String&);
	static SOCKET bind(const char *);
};

#endif

E-mail: