| 1469 | } |
| 1470 | |
| 1471 | void HttpIo::HttpImpl::writeRemote(const byte* data, size_t size, size_t from, size_t to) { |
| 1472 | std::string scriptPath(getEnv(envHTTPPOST)); |
| 1473 | if (scriptPath.empty()) { |
| 1474 | throw Error(ErrorCode::kerErrorMessage, |
| 1475 | "Please set the path of the server script to handle http post data to EXIV2_HTTP_POST " |
| 1476 | "environmental variable."); |
| 1477 | } |
| 1478 | |
| 1479 | // standardize the path without "/" at the beginning. |
| 1480 | if (scriptPath.find("://") == std::string::npos && scriptPath.front() != '/') { |
| 1481 | scriptPath = "/" + scriptPath; |
| 1482 | } |
| 1483 | |
| 1484 | Exiv2::Dictionary response; |
| 1485 | Exiv2::Dictionary request; |
| 1486 | std::string errors; |
| 1487 | |
| 1488 | Uri scriptUri = Exiv2::Uri::Parse(scriptPath); |
| 1489 | request["server"] = scriptUri.Host.empty() ? hostInfo_.Host : scriptUri.Host; |
| 1490 | if (!scriptUri.Port.empty()) |
| 1491 | request["port"] = scriptUri.Port; |
| 1492 | request["page"] = scriptUri.Path; |
| 1493 | request["verb"] = "POST"; |
| 1494 | |
| 1495 | // encode base64 |
| 1496 | size_t encodeLength = ((size + 2) / 3) * 4 + 1; |
| 1497 | std::vector<char> encodeData(encodeLength); |
| 1498 | base64encode(data, size, encodeData.data(), encodeLength); |
| 1499 | // url encode |
| 1500 | const std::string urlencodeData = urlencode(encodeData.data()); |
| 1501 | |
| 1502 | std::stringstream ss; |
| 1503 | ss << "path=" << hostInfo_.Path << "&" |
| 1504 | << "from=" << from << "&" |
| 1505 | << "to=" << to << "&" |
| 1506 | << "data=" << urlencodeData; |
| 1507 | std::string postData = ss.str(); |
| 1508 | |
| 1509 | // create the header |
| 1510 | ss.str(""); |
| 1511 | ss << "Content-Length: " << postData.length() << "\n" |
| 1512 | << "Content-Type: application/x-www-form-urlencoded\n" |
| 1513 | << "\n" |
| 1514 | << postData << "\r\n"; |
| 1515 | request["header"] = ss.str(); |
| 1516 | |
| 1517 | int serverCode = http(request, response, errors); |
| 1518 | if (serverCode < 0 || serverCode >= 400 || !errors.empty()) { |
| 1519 | throw Error(ErrorCode::kerFileOpenFailed, "http", serverCode, hostInfo_.Path); |
| 1520 | } |
| 1521 | } |
| 1522 | |
| 1523 | HttpIo::HttpIo(const std::string& url, size_t blockSize) { |
| 1524 | p_ = std::make_unique<HttpImpl>(url, blockSize); |