File: httpinput.h

package info (click to toggle)
cubemap 1.3.2-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 428 kB
  • sloc: cpp: 4,431; sh: 114; perl: 102; makefile: 60
file content (113 lines) | stat: -rw-r--r-- 3,085 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#ifndef _HTTPINPUT_H
#define _HTTPINPUT_H 1

#include <pthread.h>
#include <stddef.h>
#include <string>
#include <vector>

#include "input.h"
#include "metacube2.h"

class InputProto;

class HTTPInput : public Input {
public:
	HTTPInput(const std::string &url, Input::Encoding encoding);

	// Serialization/deserialization.
	HTTPInput(const InputProto &serialized);
	virtual InputProto serialize() const;
	
	virtual void close_socket();

	virtual std::string get_url() const { return url; }

	virtual void add_destination(int stream_index);

	virtual InputStats get_stats() const;

private:
	// Actually does the download.
	virtual void do_work();
	
	// Open a socket that connects to the given host and port. Does DNS resolving.
	int lookup_and_connect(const std::string &host, const std::string &port);

	// Parses a HTTP response. Returns false if it not a 200.
	bool parse_response(const std::string &response);

	// Stores the given data, looks for Metacube blocks (skipping data if needed),
	// and calls process_block() for each one.
	void process_data(char *ptr, size_t bytes);

	// Drops <num_bytes> bytes from the head of <pending_data>,
	// and outputs a warning.
	void drop_pending_data(size_t num_bytes);

	void process_metacube_metadata_block(const metacube2_block_header &hdr, const char *payload, uint32_t payload_size);

	enum State {
		NOT_CONNECTED,
		SENDING_REQUEST,
		RECEIVING_HEADER,
		RECEIVING_DATA,
		CLOSING_SOCKET,  // Due to error.
	};
	State state;

	std::vector<int> stream_indices;

	// The URL and its parsed components.
	std::string url;
	std::string host, port, path;

	// What the input stream is to be interpreted as (normally Metacube).
	Input::Encoding encoding;

	// The HTTP request, with headers and all.
	// Only relevant for SENDING_REQUEST.
	std::string request;

	// How many bytes we've sent of the request so far.
	// Only relevant for SENDING_REQUEST.
	size_t request_bytes_sent;

	// The HTTP response we've received so far. Only relevant for RECEIVING_HEADER.
	std::string response;

	// The HTTP response headers we want to give clients for this input.
	std::string http_header;

	// The stream heder we want to give clients for this input.
	std::string stream_header;

	// Data we have received but not fully processed yet.
	std::vector<char> pending_data;

	// If <pending_data> starts with a Metacube header,
	// this is true.
	bool has_metacube_header;

	// The socket we are downloading on (or -1).
	int sock;

	// Mutex protecting <stats>.
	mutable pthread_mutex_t stats_mutex;

	// The current statistics for this connection. Protected by <stats_mutex>.
	InputStats stats;

	// Number of (started) connection attempts since last data byte was successfully read.
	unsigned num_connection_attempts;

	// If set, don't log anything related to connections.
	// (Only set if we've had enough unsuccessful connection attempts.)
	bool suppress_logging;

	// Last time we made a connection with logging enabled.
	// (Initially at some point before the epoch.)
	timespec last_verbose_connection;
};

#endif  // !defined(_HTTPINPUT_H)