package http_parser;
import primitive.collection.ByteList;
public class ParserSettings extends http_parser.lolevel.ParserSettings {
public HTTPCallback on_message_begin;
public HTTPDataCallback on_path;
public HTTPDataCallback on_query_string;
public HTTPDataCallback on_url;
public HTTPDataCallback on_fragment;
public HTTPCallback on_status_complete;
public HTTPDataCallback on_header_field;
public HTTPDataCallback on_header_value;
public HTTPCallback on_headers_complete;
public HTTPDataCallback on_body;
public HTTPCallback on_message_complete;
public HTTPErrorCallback on_error;
private HTTPCallback _on_message_begin;
private HTTPDataCallback _on_path;
private HTTPDataCallback _on_query_string;
private HTTPDataCallback _on_url;
private HTTPDataCallback _on_fragment;
private HTTPCallback _on_status_complete;
private HTTPDataCallback _on_header_field;
private HTTPDataCallback _on_header_value;
private HTTPCallback _on_headers_complete;
private HTTPDataCallback _on_body;
private HTTPCallback _on_message_complete;
private HTTPErrorCallback _on_error;
private http_parser.lolevel.ParserSettings settings;
protected ByteList field = new ByteList();
protected ByteList value = new ByteList();
protected ByteList body = new ByteList();
public ParserSettings() {
this.settings = new http_parser.lolevel.ParserSettings();
createMirrorCallbacks();
attachCallbacks();
}
protected http_parser.lolevel.ParserSettings getLoLevelSettings() {
return this.settings;
}
private void createMirrorCallbacks() {
this._on_message_begin = new HTTPCallback() {
public int cb(HTTPParser p) {
if (null != ParserSettings.this.on_message_begin) {
return ParserSettings.this.on_message_begin.cb(p);
}
return 0;
}
};
this._on_path = new HTTPDataCallback() {
@Override
public int cb(HTTPParser p, byte[] by, int pos, int len) {
if (null != ParserSettings.this.on_path) {
return ParserSettings.this.on_path.cb(p, by, pos, len);
}
return 0;
}
};
this._on_query_string = new HTTPDataCallback() {
@Override
public int cb(HTTPParser p, byte[] by, int pos, int len) {
if (null != ParserSettings.this.on_query_string) {
return ParserSettings.this.on_query_string.cb(p, by, pos, len);
}
return 0;
}
};
this._on_url = new HTTPDataCallback() {
@Override
public int cb(HTTPParser p, byte[] by, int pos, int len) {
if (null != ParserSettings.this.on_url) {
return ParserSettings.this.on_url.cb(p, by, pos, len);
}
return 0;
}
};
this._on_fragment = new HTTPDataCallback() {
@Override
public int cb(HTTPParser p, byte[] by, int pos, int len) {
if (null != ParserSettings.this.on_fragment) {
return ParserSettings.this.on_fragment.cb(p, by, pos, len);
}
return 0;
}
};
this._on_status_complete = new HTTPCallback() {
@Override
public int cb(HTTPParser p) {
if (null != ParserSettings.this.on_status_complete) {
return ParserSettings.this.on_status_complete.cb(p);
}
return 0;
}
};
this._on_error = new HTTPErrorCallback() {
@Override
public void cb(HTTPParser parser, String error) {
if (null != ParserSettings.this.on_error) {
ParserSettings.this.on_error.cb(parser, error);
} else {
throw new HTTPException(error);
}
}
};
// (on_header_field and on_header_value shortened to on_h_*) // ———————— ———— ——————————————– // | State (prev. callback) | Callback | Description/action | // ———————— ———— ——————————————– // | nothing (first call) | on_h_field | Allocate new buffer and copy callback data | // | | | into it | // ———————— ———— ——————————————– // | value | on_h_field | New header started. | // | | | Copy current name,value buffers to headers | // | | | list and allocate new buffer for new name | // ———————— ———— ——————————————– // | field | on_h_field | Previous name continues. Reallocate name | // | | | buffer and append callback data to it | // ———————— ———— ——————————————– // | field | on_h_value | Value for current header started. Allocate | // | | | new buffer and copy callback data to it | // ———————— ———— ——————————————– // | value | on_h_value | Value continues. Reallocate value buffer | // | | | and append callback data to it | // ———————— ———— ——————————————–
this._on_header_field = new HTTPDataCallback() {
@Override
public int cb(HTTPParser p, byte[] by, int pos, int len) {
// previous value complete, call on_value with full value, reset value.
if (0 != ParserSettings.this.value.size()) {
// check we're even interested...
if (null != ParserSettings.this.on_header_value) {
byte [] valueArr = ParserSettings.this.value.toArray();
int ret = ParserSettings.this.on_header_value.cb(p, valueArr, 0, valueArr.length);
if (0 != ret) {
return ret;
}
ParserSettings.this.value.clear();
}
}
if (null == ParserSettings.this.on_header_field) {
return 0;
}
ParserSettings.this.field.addAll(by);
return 0;
}
};
this._on_header_value = new HTTPDataCallback() {
@Override
public int cb(HTTPParser p, byte[] by, int pos, int len) {
// previous field complete, call on_field with full field value, reset field.
if (0 != ParserSettings.this.field.size()) {
// check we're even interested...
if (null != ParserSettings.this.on_header_field) {
byte [] fieldArr = ParserSettings.this.field.toArray();
int ret = ParserSettings.this.on_header_field.cb(p, fieldArr, 0, fieldArr.length);
if (0 != ret) {
return ret;
}
ParserSettings.this.field.clear();
}
}
if (null == ParserSettings.this.on_header_value) {
return 0;
}
ParserSettings.this.value.addAll(by);
return 0;
}
};
this._on_headers_complete = new HTTPCallback() {
@Override
public int cb(HTTPParser parser) {
// is there an uncompleted value ... ?
if (0 != ParserSettings.this.value.size()) {
// check we're even interested...
if (null != ParserSettings.this.on_header_value) {
byte [] valueArr = ParserSettings.this.value.toArray();
int ret = ParserSettings.this.on_header_value.cb(parser, valueArr, 0, valueArr.length);
if (0 != ret) {
return ret;
}
ParserSettings.this.value.clear();
}
}
if (null != ParserSettings.this.on_headers_complete) {
return ParserSettings.this.on_headers_complete.cb(parser);
}
return 0;
}
};
this._on_body = new HTTPDataCallback() {
@Override
public int cb(HTTPParser p, byte[] by, int pos, int len) {
if (null != ParserSettings.this.on_body) {
ParserSettings.this.body.addAll(by, pos, len);
}
return 0;
}
};
this._on_message_complete = new HTTPCallback() {
@Override
public int cb(HTTPParser parser) {
if (null != ParserSettings.this.on_body) {
byte [] body = ParserSettings.this.body.toArray();
int ret = ParserSettings.this.on_body.cb(parser, body, 0, body.length);
if (0!=ret) {
return ret;
}
ParserSettings.this.body.clear();
}
if (null != ParserSettings.this.on_message_complete) {
return ParserSettings.this.on_message_complete.cb(parser);
}
return 0;
}
};
}
private void attachCallbacks() {
// these are certainly set, because we mirror them ...
this.settings.on_message_begin = this._on_message_begin;
this.settings.on_path = this._on_path;
this.settings.on_query_string = this._on_query_string;
this.settings.on_url = this._on_url;
this.settings.on_fragment = this._on_fragment;
this.settings.on_status_complete = this._on_status_complete;
this.settings.on_header_field = this._on_header_field;
this.settings.on_header_value = this._on_header_value;
this.settings.on_headers_complete = this._on_headers_complete;
this.settings.on_body = this._on_body;
this.settings.on_message_complete = this._on_message_complete;
this.settings.on_error = this._on_error;
}
}