void ParseStream()

in src/aws-cpp-sdk-core/source/config/AWSConfigFileProfileConfigLoader.cpp [113:210]


            void ParseStream(Aws::IStream& stream)
            {
                static const size_t ASSUME_EMPTY_LEN = 3;
                State currentState = START;
                Aws::String currentSectionName;
                Aws::Map<Aws::String, Aws::String> currentKeyValues;

                Aws::String rawLine;
                while(std::getline(stream, rawLine) && currentState != FAILURE)
                {
                    // Handle CR/LF line endings ("\r\n")
                    if (!rawLine.empty() && rawLine.back() == '\r') {
                        rawLine.pop_back(); // Remove carriage return character ('\r')
                    }

                    Aws::String line = rawLine.substr(0, rawLine.find_first_of(COMMENT_START)); // ignore comments
                    if (line.empty() || line.length() < ASSUME_EMPTY_LEN || line.find_first_not_of(WHITESPACE_CHARACTERS) == Aws::String::npos)
                    {
                        continue;
                    }

                    auto openPos = line.find(LEFT_BRACKET);
                    auto closePos = line.find(RIGHT_BRACKET);

                    if(openPos != std::string::npos && closePos != std::string::npos)
                    {
                        FlushSection(currentState, currentSectionName, currentKeyValues);
                        currentKeyValues.clear();
                        ParseSectionDeclaration(line, currentSectionName, currentState);
                        continue;
                    }

                    if(PROFILE_FOUND == currentState || SSO_SESSION_FOUND == currentState)
                    {
                        auto equalsPos = line.find(EQ);
                        if (equalsPos != std::string::npos)
                        {
                            auto key = StringUtils::Trim(line.substr(0, equalsPos).c_str());
                            auto value = StringUtils::Trim(line.substr(equalsPos + 1).c_str());
                            currentKeyValues[key] = value;
                            continue;
                        }
                    }

                    if(UNKNOWN_SECTION_FOUND == currentState)
                    {
                        // skip any unknown sections
                        continue;
                    }

                    AWS_LOGSTREAM_ERROR(PARSER_TAG, "Unexpected line in the aws shared profile: " << rawLine);
                    currentState = FAILURE;
                    break;
                }

                FlushSection(currentState, currentSectionName, currentKeyValues);

                // Put sso-sessions into profiles
                for(auto& profile : m_foundProfiles)
                {
                    const Aws::String& profileSsoSessionName = profile.second.GetValue(SSO_SESSION_KEY);
                    if(!profileSsoSessionName.empty())
                    {
                        auto ssoSessionIt = m_foundSsoSessions.find(profileSsoSessionName);
                        if(ssoSessionIt == m_foundSsoSessions.end())
                        {
                            AWS_LOGSTREAM_ERROR(PARSER_TAG, "AWS profile has reference to a missing sso_session: " << profileSsoSessionName);
                            currentState = FAILURE;
                            continue;
                        }
                        auto ssoSession = ssoSessionIt->second;
                        auto prof = profile.second;
                        // If sso session and profile have conflicting start url or region, fail to parse
                        // the session/sso specific profile properties
                        auto hasConflictingStartUrls = !ssoSession.GetSsoStartUrl().empty()
                                                       && !prof.GetSsoStartUrl().empty()
                                                       && ssoSession.GetSsoStartUrl() != prof.GetSsoStartUrl();
                        auto hasConflictingRegions = !ssoSession.GetSsoRegion().empty()
                                                      && !prof.GetSsoRegion().empty()
                                                      && ssoSession.GetSsoRegion() != prof.GetSsoRegion();
                        if (hasConflictingStartUrls || hasConflictingRegions) {
                            AWS_LOGSTREAM_ERROR(PARSER_TAG,
                                "SSO profile has a start url or region conflict with sso session");
                            prof.SetSsoStartUrl("");
                            prof.SetSsoRegion("");
                            prof.SetSsoAccountId("");
                            prof.SetSsoRoleName("");
                            continue;
                        }
                        profile.second.SetSsoSession(ssoSessionIt->second);
                    }
                }

                if(FAILURE == currentState)
                {
                    AWS_LOGSTREAM_ERROR(PARSER_TAG, "AWS shared profile config parsing failed");
                }
            }