public HttpHandler<File> download( HttpRequest.HttpMethod method, String url, String target, RequestParams params, boolean autoResume, boolean autoRename, RequestCallBack<File> callback) { if (url == null) throw new IllegalArgumentException("url may not be null"); if (target == null) throw new IllegalArgumentException("target may not be null"); HttpRequest request = new HttpRequest(method, url); HttpHandler<File> handler = new HttpHandler<File>(httpClient, httpContext, responseTextCharset, callback); handler.setExpiry(currentRequestExpiry); handler.setHttpRedirectHandler(httpRedirectHandler); if (params != null) { request.setRequestParams(params, handler); handler.setPriority(params.getPriority()); } handler.executeOnExecutor(EXECUTOR, request, target, autoResume, autoRename); return handler; }
public HttpHandler<File> download( String url, AjaxParams params, String target, boolean isResume, AjaxCallBack<File> callback) { final HttpGet get = new HttpGet(getUrlWithQueryString(url, params)); HttpHandler<File> handler = new HttpHandler<File>(httpClient, httpContext, callback, charset); handler.executeOnExecutor(executor, get, target, isResume); return handler; }
protected ArrayList<JSONObject> doInBackground(String... urls) { url = urls[0]; HttpHandler httpHandler = new HttpHandler(); responseJSON = httpHandler.getInformation(url, wantedService, paramsForHttpPOST, new HttpGet(url)); return responseJSON; }
private <T> HttpHandler<T> sendRequest( HttpRequest request, RequestParams params, RequestCallBack<T> callBack) { HttpHandler<T> handler = new HttpHandler<T>(httpClient, httpContext, responseTextCharset, callBack); handler.setExpiry(currentRequestExpiry); handler.setHttpRedirectHandler(httpRedirectHandler); request.setRequestParams(params, handler); handler.executeOnExecutor(executor, request); return handler; }
public boolean startUrlRequest(String url, final long callbackPtr) throws Exception { if (httpHandler == null) { return false; } httpHandler.onRequest( url, new Callback() { @Override public void onFailure(Request request, IOException e) { onUrlFailure(callbackPtr); e.printStackTrace(); } @Override public void onResponse(Response response) throws IOException { if (!response.isSuccessful()) { onUrlFailure(callbackPtr); throw new IOException("Unexpected response code: " + response); } BufferedSource source = response.body().source(); byte[] bytes = source.readByteArray(); onUrlSuccess(bytes, callbackPtr); } }); return true; }
public static void executeRootHandler( final HttpHandler handler, final HttpServerExchange exchange) { try { exchange.setInCall(true); handler.handleRequest(exchange); exchange.setInCall(false); if (exchange.isDispatched()) { final Runnable dispatchTask = exchange.getDispatchTask(); Executor executor = exchange.getDispatchExecutor(); exchange.unDispatch(); if (dispatchTask != null) { executor = executor == null ? exchange.getConnection().getWorker() : executor; executor.execute(dispatchTask); } } else { exchange.endExchange(); } } catch (Throwable t) { exchange.setInCall(false); if (!exchange.isResponseStarted()) { exchange.setResponseCode(500); } UndertowLogger.REQUEST_LOGGER.errorf(t, "Blocking request failed %s", exchange); exchange.endExchange(); } }
public void testGetResponseNoAccess() throws Exception { boolean thrown = false; try { tester.getResponse("bad url"); } catch (AccessErrorException e) { thrown = true; } assertTrue(thrown); }
// ////////////////////////////////////////////////////////////////////////////////////////////// private <T> HttpHandler<T> sendRequest( HttpRequest request, RequestParams params, RequestCallBack<T> callBack) { // liuzw. 增加安全加密步骤,加密过程可定制. if (secureInterceptor != null) { params = secureInterceptor.preSend(request, params); } HttpHandler<T> handler = new HttpHandler<T>(httpClient, httpContext, responseTextCharset, callBack); handler.setExpiry(currentRequestExpiry); handler.setHttpRedirectHandler(httpRedirectHandler); request.setRequestParams(params, handler); if (params != null) { handler.setPriority(params.getPriority()); } handler.executeOnExecutor(EXECUTOR, request); return handler; }
public void startGame(View view) { Toast.makeText(getApplicationContext(), "Listening for players", Toast.LENGTH_SHORT).show(); // btnListenForPlayers.setClickable(false); String response = HttpHandler.startNewGame(maxplayers); // Split the response string and seperate it to playerID and gameID String data[] = response.split(":", 2); String playerID = data[0]; String gameID = data[1]; int gid = Integer.parseInt(gameID); Log.d(TAG, "PlayerID: " + playerID); FileHandler.savePlayerId(Integer.parseInt(playerID), this); Log.d(TAG, "GameID: " + gameID); FileHandler.saveGamestate(gameID + ":", this); Log.d(TAG, response); TextView twServerResponse = (TextView) findViewById(R.id.twServerResponce); twServerResponse.setText(response); startService(new Intent(this, RyscService.class)); }
/* Parse a request or response line */ private boolean parseLine(ByteBuffer buffer) { boolean handle = false; // Process headers while (_state.ordinal() < State.HEADER.ordinal() && buffer.hasRemaining() && !handle) { // process each character byte ch = next(buffer); if (ch == 0) break; if (_maxHeaderBytes > 0 && ++_headerBytes > _maxHeaderBytes) { if (_state == State.URI) { LOG.warn("URI is too large >" + _maxHeaderBytes); throw new BadMessage(HttpStatus.REQUEST_URI_TOO_LONG_414); } else { if (_requestHandler != null) LOG.warn("request is too large >" + _maxHeaderBytes); else LOG.warn("response is too large >" + _maxHeaderBytes); throw new BadMessage(HttpStatus.REQUEST_ENTITY_TOO_LARGE_413); } } switch (_state) { case METHOD: if (ch == HttpTokens.SPACE) { _length = _string.length(); _methodString = takeString(); HttpMethod method = HttpMethod.CACHE.get(_methodString); if (method != null && !_strict) _methodString = method.asString(); setState(State.SPACE1); } else if (ch < HttpTokens.SPACE) throw new BadMessage(ch < 0 ? "Illegal character" : "No URI"); else _string.append((char) ch); break; case RESPONSE_VERSION: if (ch == HttpTokens.SPACE) { _length = _string.length(); String version = takeString(); _version = HttpVersion.CACHE.get(version); if (_version == null) throw new BadMessage(HttpStatus.BAD_REQUEST_400, "Unknown Version"); setState(State.SPACE1); } else if (ch < HttpTokens.SPACE) throw new BadMessage(ch < 0 ? "Illegal character" : "No Status"); else _string.append((char) ch); break; case SPACE1: if (ch > HttpTokens.SPACE || ch < 0) { if (_responseHandler != null) { setState(State.STATUS); setResponseStatus(ch - '0'); } else { _uri.clear(); setState(State.URI); // quick scan for space or EoBuffer if (buffer.hasArray()) { byte[] array = buffer.array(); int p = buffer.arrayOffset() + buffer.position(); int l = buffer.arrayOffset() + buffer.limit(); int i = p; while (i < l && array[i] > HttpTokens.SPACE) i++; int len = i - p; _headerBytes += len; if (_maxHeaderBytes > 0 && ++_headerBytes > _maxHeaderBytes) { LOG.warn("URI is too large >" + _maxHeaderBytes); throw new BadMessage(HttpStatus.REQUEST_URI_TOO_LONG_414); } if (_uri.remaining() <= len) { ByteBuffer uri = ByteBuffer.allocate(_uri.capacity() + 2 * len); _uri.flip(); uri.put(_uri); _uri = uri; } _uri.put(array, p - 1, len + 1); buffer.position(i - buffer.arrayOffset()); } else _uri.put(ch); } } else if (ch < HttpTokens.SPACE) { throw new BadMessage( HttpStatus.BAD_REQUEST_400, _requestHandler != null ? "No URI" : "No Status"); } break; case STATUS: if (ch == HttpTokens.SPACE) { setState(State.SPACE2); } else if (ch >= '0' && ch <= '9') { _responseStatus = _responseStatus * 10 + (ch - '0'); } else if (ch < HttpTokens.SPACE && ch >= 0) { handle = _responseHandler.startResponse(_version, _responseStatus, null) || handle; setState(State.HEADER); } else { throw new BadMessage(); } break; case URI: if (ch == HttpTokens.SPACE) { setState(State.SPACE2); } else if (ch < HttpTokens.SPACE && ch >= 0) { // HTTP/0.9 _uri.flip(); handle = _requestHandler.startRequest(_method, _methodString, _uri, null) || handle; setState(State.END); BufferUtil.clear(buffer); handle = _handler.headerComplete() || handle; handle = _handler.messageComplete() || handle; } else { if (!_uri.hasRemaining()) { ByteBuffer uri = ByteBuffer.allocate(_uri.capacity() * 2); _uri.flip(); uri.put(_uri); _uri = uri; } _uri.put(ch); } break; case SPACE2: if (ch > HttpTokens.SPACE) { _string.setLength(0); _string.append((char) ch); if (_responseHandler != null) { _length = 1; setState(State.REASON); } else { setState(State.REQUEST_VERSION); // try quick look ahead for HTTP Version HttpVersion version; if (buffer.position() > 0 && buffer.hasArray()) version = HttpVersion.lookAheadGet( buffer.array(), buffer.arrayOffset() + buffer.position() - 1, buffer.arrayOffset() + buffer.limit()); else version = HttpVersion.CACHE.getBest(buffer, 0, buffer.remaining()); if (version != null) { int pos = buffer.position() + version.asString().length() - 1; if (pos < buffer.limit()) { byte n = buffer.get(pos); if (n == HttpTokens.CARRIAGE_RETURN) { _cr = true; _version = version; _string.setLength(0); buffer.position(pos + 1); } else if (n == HttpTokens.LINE_FEED) { _version = version; _string.setLength(0); buffer.position(pos); } } } } } else if (ch == HttpTokens.LINE_FEED) { if (_responseHandler != null) { handle = _responseHandler.startResponse(_version, _responseStatus, null) || handle; setState(State.HEADER); } else { // HTTP/0.9 _uri.flip(); handle = _requestHandler.startRequest(_method, _methodString, _uri, null) || handle; setState(State.END); BufferUtil.clear(buffer); handle = _handler.headerComplete() || handle; handle = _handler.messageComplete() || handle; } } else if (ch < 0) throw new BadMessage(); break; case REQUEST_VERSION: if (ch == HttpTokens.LINE_FEED) { if (_version == null) { _length = _string.length(); _version = HttpVersion.CACHE.get(takeString()); } if (_version == null) throw new BadMessage(HttpStatus.BAD_REQUEST_400, "Unknown Version"); // Should we try to cache header fields? if (_connectionFields == null && _version.getVersion() >= HttpVersion.HTTP_1_1.getVersion()) { int header_cache = _handler.getHeaderCacheSize(); if (header_cache > 0) _connectionFields = new ArrayTernaryTrie<>(header_cache); } setState(State.HEADER); _uri.flip(); handle = _requestHandler.startRequest(_method, _methodString, _uri, _version) || handle; continue; } else if (ch >= HttpTokens.SPACE) _string.append((char) ch); else throw new BadMessage(); break; case REASON: if (ch == HttpTokens.LINE_FEED) { String reason = takeString(); setState(State.HEADER); handle = _responseHandler.startResponse(_version, _responseStatus, reason) || handle; continue; } else if (ch >= HttpTokens.SPACE) { _string.append((char) ch); if (ch != ' ' && ch != '\t') _length = _string.length(); } else throw new BadMessage(); break; default: throw new IllegalStateException(_state.toString()); } } return handle; }
public void cancelUrlRequest(String url) { if (httpHandler == null) { return; } httpHandler.onCancel(url); }
/** * @param activity * @param pageNo * @param pagesize * @param date * @param ifAfter true,查询以后的(当前和未来),false,查询以前的(历史) * @param isToastLoding */ public static void startGet( Activity activity, int pageNo, int pagesize, String date, final Boolean ifAfter, final Boolean isToastLoding) { if (isToastLoding) { mToastLoding = new ToastLoding(activity, "努力获取中"); mToastLoding.show(); } Log.d(Tag + "date", date); mactivity = activity; mHttpHandler = new HttpHandler(activity); JSONObject JsonPageNo = new JSONObject(); try { JsonPageNo.put("pageNo", pageNo); JsonPageNo.put("pageSize", pagesize); JsonPageNo.put("date", date); JsonPageNo.put("ifAfter", ifAfter); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } mHttpHandler.addJSONObject(JsonPageNo); mHttpHandler.startHandler(HttpUrlList.httpgetMemoListURl); mHttpHandler.setOnHttpRequestListener( new OnHttpRequestListener() { @Override public void startHttpRequest(String message) { // TODO Auto-generated method stub } @Override public void onHttpRequestDone(String data) { // TODO Auto-generated method stub Log.d(Tag + "JsongetVcodeResult", data); JsonResult(data); if (isToastLoding && null != MainActivity.getMainActivity()) { if (ifAfter) { MainActivity.getMainActivity().clickNowData(); } else { MainActivity.getMainActivity().clickHisData(); } } if (null != mToastLoding && mToastLoding.isShowing()) { mToastLoding.cancel(); } } @Override public void onError(String message) { // TODO Auto-generated method stub if (null != mToastLoding && mToastLoding.isShowing()) { mToastLoding.cancel(); } new ToastDialog(mactivity, message).show(); } }); }
protected boolean parseContent(ByteBuffer buffer) { int remaining = buffer.remaining(); if (remaining == 0 && _state == State.CONTENT) { long content = _contentLength - _contentPosition; if (content == 0) { setState(State.END); return _handler.messageComplete(); } } // Handle _content byte ch; while (_state.ordinal() < State.END.ordinal() && remaining > 0) { switch (_state) { case EOF_CONTENT: _contentChunk = buffer.asReadOnlyBuffer(); _contentPosition += remaining; buffer.position(buffer.position() + remaining); if (_handler.content(_contentChunk)) return true; break; case CONTENT: { long content = _contentLength - _contentPosition; if (content == 0) { setState(State.END); return _handler.messageComplete(); } else { _contentChunk = buffer.asReadOnlyBuffer(); // limit content by expected size if (remaining > content) { // We can cast remaining to an int as we know that it is // smaller than // or equal to length which is already an int. _contentChunk.limit(_contentChunk.position() + (int) content); } _contentPosition += _contentChunk.remaining(); buffer.position(buffer.position() + _contentChunk.remaining()); if (_handler.content(_contentChunk)) return true; if (_contentPosition == _contentLength) { setState(State.END); return _handler.messageComplete(); } } break; } case CHUNKED_CONTENT: { ch = next(buffer); if (ch > HttpTokens.SPACE) { _chunkLength = TypeUtils.convertHexDigit(ch); _chunkPosition = 0; setState(State.CHUNK_SIZE); } break; } case CHUNK_SIZE: { ch = next(buffer); if (ch == 0) break; if (ch == HttpTokens.LINE_FEED) { if (_chunkLength == 0) setState(State.CHUNK_END); else setState(State.CHUNK); } else if (ch <= HttpTokens.SPACE || ch == HttpTokens.SEMI_COLON) setState(State.CHUNK_PARAMS); else _chunkLength = _chunkLength * 16 + TypeUtils.convertHexDigit(ch); break; } case CHUNK_PARAMS: { ch = next(buffer); if (ch == HttpTokens.LINE_FEED) { if (_chunkLength == 0) setState(State.CHUNK_END); else setState(State.CHUNK); } break; } case CHUNK: { int chunk = _chunkLength - _chunkPosition; if (chunk == 0) { setState(State.CHUNKED_CONTENT); } else { _contentChunk = buffer.asReadOnlyBuffer(); if (remaining > chunk) _contentChunk.limit(_contentChunk.position() + chunk); chunk = _contentChunk.remaining(); _contentPosition += chunk; _chunkPosition += chunk; buffer.position(buffer.position() + chunk); if (_handler.content(_contentChunk)) return true; } break; } case CHUNK_END: { // TODO handle chunk trailer ch = next(buffer); if (ch == 0) break; if (ch == HttpTokens.LINE_FEED) { setState(State.END); return _handler.messageComplete(); } throw new IllegalCharacterException(_state, ch, buffer); } case CLOSED: { BufferUtils.clear(buffer); return false; } default: break; } remaining = buffer.remaining(); } return false; }
private void parsedHeader() { // handler last header if any. Delayed to here just in case there was a // continuation line (above) if (_headerString != null || _valueString != null) { // Handle known headers if (_header != null) { boolean add_to_connection_trie = false; switch (_header) { case CONTENT_LENGTH: if (_endOfContent != EndOfContent.CHUNKED_CONTENT) { try { _contentLength = Long.parseLong(_valueString); } catch (NumberFormatException e) { throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Bad Content-Length"); } if (_contentLength <= 0) _endOfContent = EndOfContent.NO_CONTENT; else _endOfContent = EndOfContent.CONTENT_LENGTH; } break; case TRANSFER_ENCODING: if (_value == HttpHeaderValue.CHUNKED) _endOfContent = EndOfContent.CHUNKED_CONTENT; else { if (_valueString.endsWith(HttpHeaderValue.CHUNKED.toString())) _endOfContent = EndOfContent.CHUNKED_CONTENT; else if (_valueString.contains(HttpHeaderValue.CHUNKED.toString())) { throw new BadMessageException(HttpStatus.BAD_REQUEST_400, "Bad chunking"); } } break; case HOST: _host = true; if (!(_field instanceof HostPortHttpField)) { _field = new HostPortHttpField( _header, _strict ? _headerString : _header.asString(), _valueString); add_to_connection_trie = _connectionFields != null; } break; case CONNECTION: // Don't cache if not persistent if (_valueString != null && _valueString.contains("close")) _connectionFields = null; break; case AUTHORIZATION: case ACCEPT: case ACCEPT_CHARSET: case ACCEPT_ENCODING: case ACCEPT_LANGUAGE: case COOKIE: case CACHE_CONTROL: case USER_AGENT: add_to_connection_trie = _connectionFields != null && _field == null; break; default: break; } if (add_to_connection_trie && !_connectionFields.isFull() && _header != null && _valueString != null) { if (_field == null) _field = new HttpField(_header, _strict ? _headerString : _header.asString(), _valueString); _connectionFields.put(_field); } } _handler.parsedHeader( _field != null ? _field : new HttpField(_header, _headerString, _valueString)); } _headerString = _valueString = null; _header = null; _value = null; _field = null; }
/* * Parse the message headers and return true if the handler has signaled for a return */ protected boolean parseHeaders(ByteBuffer buffer) { boolean handle = false; // Process headers while (_state.ordinal() < State.CONTENT.ordinal() && buffer.hasRemaining() && !handle) { // process each character byte ch = next(buffer); if (ch == 0) break; if (_maxHeaderBytes > 0 && ++_headerBytes > _maxHeaderBytes) { LOG.warn("Header is too large >" + _maxHeaderBytes); throw new BadMessage(HttpStatus.REQUEST_ENTITY_TOO_LARGE_413); } switch (_state) { case HEADER: switch (ch) { case HttpTokens.COLON: case HttpTokens.SPACE: case HttpTokens.TAB: { // header value without name - continuation? if (_valueString == null) { _string.setLength(0); _length = 0; } else { setString(_valueString); _string.append(' '); _length++; _valueString = null; } setState(State.HEADER_VALUE); break; } default: { // handler last header if any. Delayed to here just in case there was a // continuation line (above) if (_headerString != null || _valueString != null) { // Handle known headers if (_header != null && handleKnownHeaders(buffer)) { _headerString = _valueString = null; _header = null; _value = null; _field = null; return true; } handle = _handler.parsedHeader( _field != null ? _field : new HttpField(_header, _headerString, _valueString)) || handle; } _headerString = _valueString = null; _header = null; _value = null; _field = null; // now handle the ch if (ch == HttpTokens.LINE_FEED) { _contentPosition = 0; // End of headers! // Was there a required host header? if (!_host && _version != HttpVersion.HTTP_1_0 && _requestHandler != null) { throw new BadMessage(HttpStatus.BAD_REQUEST_400, "No Host"); } // is it a response that cannot have a body? if (_responseHandler != null && // response (_responseStatus == 304 || // not-modified response _responseStatus == 204 || // no-content response _responseStatus < 200)) // 1xx response _endOfContent = EndOfContent.NO_CONTENT; // ignore any other headers set // else if we don't know framing else if (_endOfContent == EndOfContent.UNKNOWN_CONTENT) { if (_responseStatus == 0 // request || _responseStatus == 304 // not-modified response || _responseStatus == 204 // no-content response || _responseStatus < 200) // 1xx response _endOfContent = EndOfContent.NO_CONTENT; else _endOfContent = EndOfContent.EOF_CONTENT; } // How is the message ended? switch (_endOfContent) { case EOF_CONTENT: setState(State.EOF_CONTENT); handle = _handler.headerComplete() || handle; break; case CHUNKED_CONTENT: setState(State.CHUNKED_CONTENT); handle = _handler.headerComplete() || handle; break; case NO_CONTENT: handle = _handler.headerComplete() || handle; setState(State.END); handle = _handler.messageComplete() || handle; break; default: setState(State.CONTENT); handle = _handler.headerComplete() || handle; break; } } else if (ch <= HttpTokens.SPACE) throw new BadMessage(); else { if (buffer.hasRemaining()) { // Try a look ahead for the known header name and value. HttpField field = _connectionFields == null ? null : _connectionFields.getBest(buffer, -1, buffer.remaining()); if (field == null) field = CACHE.getBest(buffer, -1, buffer.remaining()); if (field != null) { final String n; final String v; if (_strict) { // Have to get the fields exactly from the buffer to match case String fn = field.getName(); String fv = field.getValue(); n = BufferUtil.toString( buffer, buffer.position() - 1, fn.length(), StandardCharsets.US_ASCII); if (fv == null) v = null; else { v = BufferUtil.toString( buffer, buffer.position() + fn.length() + 1, fv.length(), StandardCharsets.ISO_8859_1); field = new HttpField(field.getHeader(), n, v); } } else { n = field.getName(); v = field.getValue(); } _header = field.getHeader(); _headerString = n; if (v == null) { // Header only setState(State.HEADER_VALUE); _string.setLength(0); _length = 0; buffer.position(buffer.position() + n.length() + 1); break; } else { // Header and value int pos = buffer.position() + n.length() + v.length() + 1; byte b = buffer.get(pos); if (b == HttpTokens.CARRIAGE_RETURN || b == HttpTokens.LINE_FEED) { _field = field; _valueString = v; setState(State.HEADER_IN_VALUE); if (b == HttpTokens.CARRIAGE_RETURN) { _cr = true; buffer.position(pos + 1); } else buffer.position(pos); break; } else { setState(State.HEADER_IN_VALUE); setString(v); buffer.position(pos); break; } } } } // New header setState(State.HEADER_IN_NAME); _string.setLength(0); _string.append((char) ch); _length = 1; } } } break; case HEADER_IN_NAME: if (ch == HttpTokens.COLON || ch == HttpTokens.LINE_FEED) { if (_headerString == null) { _headerString = takeString(); _header = HttpHeader.CACHE.get(_headerString); } _length = -1; setState(ch == HttpTokens.LINE_FEED ? State.HEADER : State.HEADER_VALUE); break; } if (ch >= HttpTokens.SPACE || ch == HttpTokens.TAB) { if (_header != null) { setString(_header.asString()); _header = null; _headerString = null; } _string.append((char) ch); if (ch > HttpTokens.SPACE) _length = _string.length(); break; } throw new BadMessage("Illegal character"); case HEADER_VALUE: if (ch > HttpTokens.SPACE || ch < 0) { _string.append((char) (0xff & ch)); _length = _string.length(); setState(State.HEADER_IN_VALUE); break; } if (ch == HttpTokens.SPACE || ch == HttpTokens.TAB) break; if (ch == HttpTokens.LINE_FEED) { if (_length > 0) { _value = null; _valueString = (_valueString == null) ? takeString() : (_valueString + " " + takeString()); } setState(State.HEADER); break; } throw new BadMessage("Illegal character"); case HEADER_IN_VALUE: if (ch >= HttpTokens.SPACE || ch < 0) { if (_valueString != null) { setString(_valueString); _valueString = null; _field = null; } _string.append((char) (0xff & ch)); if (ch > HttpTokens.SPACE || ch < 0) _length = _string.length(); break; } if (ch == HttpTokens.LINE_FEED) { if (_length > 0) { _value = null; _valueString = takeString(); _length = -1; } setState(State.HEADER); break; } throw new BadMessage("Illegal character"); default: throw new IllegalStateException(_state.toString()); } } return handle; }
/** * Parse until next Event. * * @param buffer the buffer to parse * @return True if an {@link RequestHandler} method was called and it returned true; */ public boolean parseNext(ByteBuffer buffer) { if (DEBUG) log.debug("parseNext s={} {}", _state, BufferUtils.toDetailString(buffer)); try { // Start a request/response if (_state == State.START) { _version = null; _method = null; _methodString = null; _endOfContent = EndOfContent.UNKNOWN_CONTENT; _header = null; if (quickStart(buffer)) return true; } // Request/response line if (_state.ordinal() >= State.START.ordinal() && _state.ordinal() < State.HEADER.ordinal()) { if (parseLine(buffer)) return true; } // parse headers if (_state.ordinal() >= State.HEADER.ordinal() && _state.ordinal() < State.CONTENT.ordinal()) { if (parseHeaders(buffer)) return true; } // parse content if (_state.ordinal() >= State.CONTENT.ordinal() && _state.ordinal() < State.END.ordinal()) { // Handle HEAD response if (_responseStatus > 0 && _headResponse) { setState(State.END); return _handler.messageComplete(); } else { if (parseContent(buffer)) return true; } } // handle end states if (_state == State.END) { // eat white space while (buffer.remaining() > 0 && buffer.get(buffer.position()) <= HttpTokens.SPACE) buffer.get(); } else if (_state == State.CLOSE) { // Seeking EOF if (BufferUtils.hasContent(buffer)) { // Just ignore data when closed _headerBytes += buffer.remaining(); BufferUtils.clear(buffer); if (_maxHeaderBytes > 0 && _headerBytes > _maxHeaderBytes) { // Don't want to waste time reading data of a closed // request throw new IllegalStateException("too much data seeking EOF"); } } } else if (_state == State.CLOSED) { BufferUtils.clear(buffer); } // Handle EOF if (_eof && !buffer.hasRemaining()) { switch (_state) { case CLOSED: break; case START: setState(State.CLOSED); _handler.earlyEOF(); break; case END: case CLOSE: setState(State.CLOSED); break; case EOF_CONTENT: setState(State.CLOSED); return _handler.messageComplete(); case CONTENT: case CHUNKED_CONTENT: case CHUNK_SIZE: case CHUNK_PARAMS: case CHUNK: setState(State.CLOSED); _handler.earlyEOF(); break; default: if (DEBUG) log.debug("{} EOF in {}", this, _state); setState(State.CLOSED); _handler.badMessage(400, null); break; } } } catch (BadMessageException e) { BufferUtils.clear(buffer); Throwable cause = e.getCause(); boolean stack = log.isDebugEnable() || (!(cause instanceof NumberFormatException) && (cause instanceof RuntimeException || cause instanceof Error)); if (stack) log.warn( "bad HTTP parsed: " + e._code + (e.getReason() != null ? " " + e.getReason() : "") + " for " + _handler, e); else log.warn( "bad HTTP parsed: " + e._code + (e.getReason() != null ? " " + e.getReason() : "") + " for " + _handler); setState(State.CLOSE); _handler.badMessage(e.getCode(), e.getReason()); } catch (NumberFormatException | IllegalStateException e) { BufferUtils.clear(buffer); log.warn("parse exception: {} in {} for {}", e.toString(), _state, _handler); if (DEBUG) log.debug("parse exception", e); switch (_state) { case CLOSED: break; case CLOSE: _handler.earlyEOF(); break; default: setState(State.CLOSE); _handler.badMessage(400, null); } } catch (Exception | Error e) { BufferUtils.clear(buffer); log.warn("parse exception: " + e.toString() + " for " + _handler, e); switch (_state) { case CLOSED: break; case CLOSE: _handler.earlyEOF(); break; default: setState(State.CLOSE); _handler.badMessage(400, null); } } return false; }
protected boolean parseContent(ByteBuffer buffer) { // Handle _content byte ch; while (_state.ordinal() < State.END.ordinal() && buffer.hasRemaining()) { switch (_state) { case EOF_CONTENT: _contentChunk = buffer.asReadOnlyBuffer(); _contentPosition += _contentChunk.remaining(); buffer.position(buffer.position() + _contentChunk.remaining()); if (_handler.content(_contentChunk)) return true; break; case CONTENT: { long remaining = _contentLength - _contentPosition; if (remaining == 0) { setState(State.END); if (_handler.messageComplete()) return true; } else { _contentChunk = buffer.asReadOnlyBuffer(); // limit content by expected size if (_contentChunk.remaining() > remaining) { // We can cast remaining to an int as we know that it is smaller than // or equal to length which is already an int. _contentChunk.limit(_contentChunk.position() + (int) remaining); } _contentPosition += _contentChunk.remaining(); buffer.position(buffer.position() + _contentChunk.remaining()); boolean handle = _handler.content(_contentChunk); if (_contentPosition == _contentLength) { setState(State.END); if (_handler.messageComplete()) return true; } if (handle) return true; } break; } case CHUNKED_CONTENT: { ch = next(buffer); if (ch > HttpTokens.SPACE) { _chunkLength = TypeUtil.convertHexDigit(ch); _chunkPosition = 0; setState(State.CHUNK_SIZE); } break; } case CHUNK_SIZE: { ch = next(buffer); if (ch == 0) break; if (ch == HttpTokens.LINE_FEED) { if (_chunkLength == 0) { setState(State.END); if (_handler.messageComplete()) return true; } else setState(State.CHUNK); } else if (ch <= HttpTokens.SPACE || ch == HttpTokens.SEMI_COLON) setState(State.CHUNK_PARAMS); else _chunkLength = _chunkLength * 16 + TypeUtil.convertHexDigit(ch); break; } case CHUNK_PARAMS: { ch = next(buffer); if (ch == HttpTokens.LINE_FEED) { if (_chunkLength == 0) { setState(State.END); if (_handler.messageComplete()) return true; } else setState(State.CHUNK); } break; } case CHUNK: { int remaining = _chunkLength - _chunkPosition; if (remaining == 0) { setState(State.CHUNKED_CONTENT); } else { _contentChunk = buffer.asReadOnlyBuffer(); if (_contentChunk.remaining() > remaining) _contentChunk.limit(_contentChunk.position() + remaining); remaining = _contentChunk.remaining(); _contentPosition += remaining; _chunkPosition += remaining; buffer.position(buffer.position() + remaining); if (_handler.content(_contentChunk)) return true; } break; } case CLOSED: { BufferUtil.clear(buffer); return false; } default: break; } } return false; }
/** * Parse until next Event. * * @return True if an {@link RequestHandler} method was called and it returned true; */ public boolean parseNext(ByteBuffer buffer) { if (DEBUG) LOG.debug("parseNext s={} {}", _state, BufferUtil.toDetailString(buffer)); try { boolean handle = false; // Start a request/response if (_state == State.START) { _version = null; _method = null; _methodString = null; _endOfContent = EndOfContent.UNKNOWN_CONTENT; _header = null; handle = quickStart(buffer); } // Request/response line if (!handle && _state.ordinal() >= State.START.ordinal() && _state.ordinal() < State.HEADER.ordinal()) handle = parseLine(buffer); // parse headers if (!handle && _state.ordinal() >= State.HEADER.ordinal() && _state.ordinal() < State.CONTENT.ordinal()) handle = parseHeaders(buffer); // parse content if (!handle && _state.ordinal() >= State.CONTENT.ordinal() && _state.ordinal() < State.END.ordinal()) { // Handle HEAD response if (_responseStatus > 0 && _headResponse) { setState(State.END); handle = _handler.messageComplete(); } else handle = parseContent(buffer); } // handle end states if (_state == State.END) { // eat white space while (buffer.remaining() > 0 && buffer.get(buffer.position()) <= HttpTokens.SPACE) buffer.get(); } else if (_state == State.CLOSED) { if (BufferUtil.hasContent(buffer)) { // Just ignore data when closed _headerBytes += buffer.remaining(); BufferUtil.clear(buffer); if (_headerBytes > _maxHeaderBytes) { // Don't want to waste time reading data of a closed request throw new IllegalStateException("too much data after closed"); } } } // Handle EOF if (_eof && !buffer.hasRemaining()) { switch (_state) { case CLOSED: break; case START: _handler.earlyEOF(); setState(State.CLOSED); break; case END: setState(State.CLOSED); break; case EOF_CONTENT: handle = _handler.messageComplete() || handle; setState(State.CLOSED); break; case CONTENT: case CHUNKED_CONTENT: case CHUNK_SIZE: case CHUNK_PARAMS: case CHUNK: _handler.earlyEOF(); setState(State.CLOSED); break; default: if (DEBUG) LOG.debug("{} EOF in {}", this, _state); _handler.badMessage(400, null); setState(State.CLOSED); break; } } return handle; } catch (BadMessage e) { BufferUtil.clear(buffer); LOG.warn( "badMessage: " + e._code + (e._message != null ? " " + e._message : "") + " for " + _handler); if (DEBUG) LOG.debug(e); setState(State.CLOSED); _handler.badMessage(e._code, e._message); return false; } catch (Exception e) { BufferUtil.clear(buffer); LOG.warn("badMessage: " + e.toString() + " for " + _handler); if (DEBUG) LOG.debug(e); if (_state.ordinal() <= State.END.ordinal()) { setState(State.CLOSED); _handler.badMessage(400, null); } else { _handler.earlyEOF(); setState(State.CLOSED); } return false; } }
/** * Processes the provided {@link ApacheSection} (i.e., .htaccess) for instructions and options * * @param handler The {@link HttpHandler} * @return Will return false if the current request should halt, i.e., the request was already * handled by the directives */ public boolean handleDirectives(ApacheSection apache, HttpHandler handler) throws ApacheDirectiveException { boolean def = true; for (ApacheDirective kv : apache.directives()) { String key = kv.getKey(); String[] args = kv.getArguments(); HttpRequestWrapper request = handler.getRequest(); // HttpResponseWrapper response = handler.getResponse(); WebInterpreter fi = handler.getInterpreter(); Site site = handler.getSite(); switch (key) { /** Section Types */ case "IfDefine": kv.isSection(); kv.hasArguments(1, "<Startup Argument>"); if (AppLoader.options().has(args[0]) || AppLoader.options().hasArgument(args[0])) if (!handleDirectives((ApacheSection) kv, handler)) def = false; break; case "IfModule": // TODO Implement detection of common Apache modules the server can // currently imitate, e.g., Rewrite kv.isSection(); kv.hasArguments(1, "<plugin>"); if (PluginManager.instance().getPluginByNameWithoutException(args[0]) != null || PluginManager.instance().getPluginByClassnameWithoutException(args[0]) != null) if (!handleDirectives((ApacheSection) kv, handler)) def = false; break; case "IfVersion": kv.isSection(); kv.hasArguments(2, "<operator> <version>"); if (StringFunc.compareVersions(Versioning.getVersionNumber(), args[1], args[0])) if (!handleDirectives((ApacheSection) kv, handler)) def = false; break; case "Directory": kv.isSection(); kv.hasArguments(1, "<directory>"); if (fi.hasFile()) { String rel = fi.getFilePath() .substring( site.getSubdomain(request.getSubdomain()) .directory() .getAbsolutePath() .length()); if (rel.startsWith("/")) rel = rel.substring(1); if (args[0].startsWith("/") && (fi.getFilePath().startsWith(args[0]) || ("/" + rel).startsWith(args[0])) || rel.startsWith(args[0])) if (!handleDirectives((ApacheSection) kv, handler)) def = false; } break; /** Individual Key/Values */ case "ErrorDocument": ErrorDocument doc = ErrorDocument.parseArgs(args); errorDocuments.put(doc.getHttpCode(), doc); break; case "AllowOverride": for (String a : args) if (a.equalsIgnoreCase("All")) for (Override o : overrides) o.allow(); else if (a.equalsIgnoreCase("None")) for (Override o : overrides) o.deny(); else { Override o = override(a.contains("=") ? a.substring(0, a.indexOf("=")) : a); if (o == null) throw new ApacheDirectiveException( "The 'AllowOverride' directive does not reconize the option '" + a + "'", kv); if ((o == overrides.overrideNonfatal || o == overrides.overrideOptions) && a.contains("=")) o.setParams(a.substring(a.indexOf("=") + 1)); o.allow(); } break; case "Location": kv.isSection(); kv.hasArguments(1, "<url>"); if (request.getUri().startsWith(args[0])) if (!handleDirectives((ApacheSection) kv, handler)) def = false; break; case "LocationMatch": kv.isSection(); kv.hasArguments(1, "<url regex>"); if (request.getUri().matches(args[0])) if (!handleDirectives((ApacheSection) kv, handler)) def = false; break; case "Options": if (overrides.overrideOptions.allowed()) for (String a : args) { if ((a.startsWith("+") || a.startsWith("-") ? a.substring(1) : a) .equalsIgnoreCase("All")) { for (Option o : options) if (o != options.optionMultiViews) if (a.startsWith("-")) o.disable(); else o.enable(); } else { Option o = option(a.startsWith("+") || a.startsWith("-") ? a.substring(1) : a); if (o == null) throw new ApacheDirectiveException( "The 'Options' directive does not reconize the option '" + a + "'", kv); if (a.startsWith("-")) o.disable(); else o.enable(); } } else throw new ApacheDirectiveException( "The directive 'Option' has been forbidden here", kv); break; case "VirtualHost": throw new ApacheDirectiveException( "You can not define a new site using the VirtualHost directive here, site configs are located within the webroot."); case "Proxy": case "ProxyMatch": case "ProxyPass": throw new ApacheDirectiveException( "The module mod_proxy is exclusive to the Apache Web Server. We currently have no implementation, nor interest, to support said directives."); default: throw new ApacheDirectiveException( "Currently the Apache directive '" + key + "' is not implemented", kv); } // ErrorDocument 403 http://www.yahoo.com/ // Order deny,allow // Deny from all // Allow from 208.113.134.190 } return def; }