blob: cd1d9a03437b133f6bf0e6e7a158de5796e2ff87 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <decaf/net/HttpURLConnection.h>
#include <decaf/lang/Integer.h>
#include <decaf/lang/exceptions/IllegalStateException.h>
#include <decaf/net/ProtocolException.h>
using namespace decaf;
using namespace decaf::lang;
using namespace decaf::lang::exceptions;
using namespace decaf::net;
////////////////////////////////////////////////////////////////////////////////
bool HttpURLConnection::followRedirects = true;
const int HttpURLConnection::DEFAULT_CHUNK_LENGTH = 1024;
const int HttpURLConnection::HTTP_ACCEPTED = 202;
const int HttpURLConnection::HTTP_BAD_GATEWAY = 502;
const int HttpURLConnection::HTTP_BAD_METHOD = 405;
const int HttpURLConnection::HTTP_BAD_REQUEST = 400;
const int HttpURLConnection::HTTP_CLIENT_TIMEOUT = 408;
const int HttpURLConnection::HTTP_CONFLICT = 409;
const int HttpURLConnection::HTTP_CREATED = 201;
const int HttpURLConnection::HTTP_ENTITY_TOO_LARGE = 413;
const int HttpURLConnection::HTTP_FORBIDDEN = 403;
const int HttpURLConnection::HTTP_GATEWAY_TIMEOUT = 504;
const int HttpURLConnection::HTTP_GONE = 410;
const int HttpURLConnection::HTTP_INTERNAL_ERROR = 500;
const int HttpURLConnection::HTTP_LENGTH_REQUIRED = 411;
const int HttpURLConnection::HTTP_MOVED_PERM = 301;
const int HttpURLConnection::HTTP_MOVED_TEMP = 302;
const int HttpURLConnection::HTTP_MULT_CHOICE = 300;
const int HttpURLConnection::HTTP_NO_CONTENT = 204;
const int HttpURLConnection::HTTP_NOT_ACCEPTABLE = 406;
const int HttpURLConnection::HTTP_NOT_AUTHORITATIVE = 203;
const int HttpURLConnection::HTTP_NOT_FOUND = 404;
const int HttpURLConnection::HTTP_NOT_IMPLEMENTED = 501;
const int HttpURLConnection::HTTP_NOT_MODIFIED = 304;
const int HttpURLConnection::HTTP_OK = 200;
const int HttpURLConnection::HTTP_PARTIAL = 206;
const int HttpURLConnection::HTTP_PAYMENT_REQUIRED = 402;
const int HttpURLConnection::HTTP_PRECON_FAILED = 412;
const int HttpURLConnection::HTTP_PROXY_AUTH = 407;
const int HttpURLConnection::HTTP_REQ_TOO_LONG = 414;
const int HttpURLConnection::HTTP_RESET = 205;
const int HttpURLConnection::HTTP_SEE_OTHER = 303;
const int HttpURLConnection::HTTP_USE_PROXY = 305;
const int HttpURLConnection::HTTP_UNAUTHORIZED = 401;
const int HttpURLConnection::HTTP_UNSUPPORTED_TYPE = 415;
const int HttpURLConnection::HTTP_UNAVAILABLE = 503;
const int HttpURLConnection::HTTP_VERSION = 505;
////////////////////////////////////////////////////////////////////////////////
HttpURLConnection::HttpURLConnection(const URL& url) : URLConnection(url),
method("GET"),
responseCode(-1),
responseMessage(),
instanceFollowRedirects(true),
chunkLength(-1),
fixedContentLength(-1) {
}
////////////////////////////////////////////////////////////////////////////////
HttpURLConnection::~HttpURLConnection() {
}
////////////////////////////////////////////////////////////////////////////////
int HttpURLConnection::getResponseCode() {
// Call getInputStream() first since getHeaderField() doesn't return exceptions
getInputStream();
std::string response = getHeaderField(0);
if (response == "") {
return -1;
}
// TODO response = response.trim();
std::size_t mark = response.find_first_of(" ") + 1;
if (mark == std::string::npos) {
return -1;
}
std::size_t last = mark + 3;
if (last > response.length()) {
last = response.length();
}
responseCode = Integer::parseInt(response.substr(mark, mark + last));
if (last + 1 <= response.length()) {
responseMessage = response.substr(last + 1);
}
return responseCode;
}
////////////////////////////////////////////////////////////////////////////////
std::string HttpURLConnection::getResponseMessage() {
if (responseMessage != "") {
return responseMessage;
}
getResponseCode();
return responseMessage;
}
////////////////////////////////////////////////////////////////////////////////
void HttpURLConnection::setRequestMethod(const std::string& method DECAF_UNUSED) {
if (connected) {
throw ProtocolException(__FILE__, __LINE__, "Connection already established");
}
// TODO
// for (int i = 0; i < methodTokens.length; i++) {
// if (methodTokens[i].equals(method)) {
// // if there is a supported method that matches the desired
// // method, then set the current method and return
// this.method = methodTokens[i];
// return;
// }
// }
// if none matches, then throw ProtocolException
throw new ProtocolException();
}
////////////////////////////////////////////////////////////////////////////////
void HttpURLConnection::setFixedLengthStreamingMode(int contentLength) {
if (connected) {
throw IllegalStateException(__FILE__, __LINE__, "Already connected");
}
if (0 < chunkLength) {
throw IllegalStateException(__FILE__, __LINE__, "different mode already set");
}
if (0 > contentLength) {
throw IllegalArgumentException(__FILE__, __LINE__, "scale value < than zero");
}
fixedContentLength = contentLength;
}
////////////////////////////////////////////////////////////////////////////////
void HttpURLConnection::setChunkedStreamingMode(int chunklen) {
if (connected) {
throw IllegalStateException(__FILE__, __LINE__, "Already connected");
}
if (0 <= fixedContentLength) {
throw IllegalStateException(__FILE__, __LINE__, "different mode already set");
}
if (0 >= chunklen) {
chunkLength = DEFAULT_CHUNK_LENGTH;
} else {
chunkLength = chunklen;
}
}